2013-03-13 45 views
2

我正在寻找一种惯用的方法来打印以逗号分隔的序列中的每个项目,而不打印结尾的逗号。我想避免使用clojure.string/join,因为我不想创建一个中间字符串(这就是我之前做的事情,代码更难以遵循)。我宁愿只打印元素。在seq中的每个项目之间打印逗号

这就是我现在所拥有的:

(doseq [element a-map] 
    (printf "%s = %s" (key element) (val element)) 
    (print ", ")) 

我能想到的几种方法可以做到这一点:

  1. 打印的第一项doseq外面,然后用打印每个项目前面的逗号。

    (printf "%s = %s" (key (first a-map)) (val (first a-map))) 
    (doseq [element (rest a-map)] 
        (print ", ") 
        (printf "%s = %s" (key element) (val element))) 
    
  2. 打印除了最后跟一个逗号的所有项目,然后再打印doseq之外的最后一个项目。代码与第一个选项类似,但对于不是随机访问的seq,效率不高。

  3. 使用interpose并检查element是否为字符串。

    (doseq [element (interpose ", " a-map)] 
        (if (str? element) 
        (print element) 
        (printf "%s = %s" (key element) (val element)))) 
    

我不喜欢1或2,因为重复的。由于if条件,我不喜欢3。

+0

为什么你需要检查元素是#3中的一个字符串 - 你还期望它是什么?顺便说一句,为什么你需要在#3中打印(打印元素)? – 9000 2013-03-13 20:51:13

+0

哦,看起来我有一些拼写错误,我使用'a-map'而不是'element'。但为了回答你的问题,我期望'element'可以是来自'a-map'的字符串或地图元素。 – Brigham 2013-03-13 20:53:44

回答

3

OK,这里是一个新的尝试:

(defn str-commas [a-map] 
    (doseq [[[k v] sep] (partition-all 2 (interpose ", " a-map))] 
    (printf "%s = %s%s" k v (or sep "")))) 

partition大小为N的回报清单,但由于插入逗号不会创建偶数的元素,最后的键值对被放弃了。 partition-all可能包含具有较少元素的分区(最后一个元素仅包含键值对)。

诀窍是使用(or sep ""),因为我们知道最后一个元素将缺少分隔符,因此它将为空。

+0

不幸的是,这只是等同于'(clojure.string/join ...)',我试图避免为此代码创建一个中间字符串。 – Brigham 2013-03-13 22:35:18

+0

@布里汉姆 - 这个版本应该没有中间字符串 – 2013-03-13 23:47:37

+0

很酷,这是一个很好的方式来做到这一点。 – Brigham 2013-03-14 00:18:52

相关问题