clojure提高了过滤二维列表的可读性

时间:2015-12-31 20:30:16

标签: clojure code-readability

当前代码采用如下输入: [[:k1 0] [:k1 1] [:k2 2]] 并组织列表中具有相同关键字的项目: (([:k1 0] [:k1 1]) ([:k2 2]))

以下代码有效,但我觉得可以改进。嵌套 map #(filter看起来很丑,我想我可以使用clojure for函数以优雅的代码生成相同的结果。

如何提高可读性?

(defn list-of-equals [itens]
  (let [get-key (fn [[k]] k)
        keys (->> itens (map get-key) distinct)
        pairs (map #(filter (fn [[k]]
                              (= % k)) itens)  keys)]
      pairs))

1 个答案:

答案 0 :(得分:2)

您遇到的问题是您必须针对每个不同的密钥迭代列表。如果你使用(defn for-filter [items val] (for [i items :when (= (first i) (first val))] i)) ,它可能看起来像这样。

(group-by first items)
    => {:k1 [[:k1 0] [:k1 1]], :k2 [[:k2 2]]}

虽然这可能有点清洁,但使用标准库可以使它更简洁。如果我们进行分组操作,我们可以一次性收集具有相同密钥的所有项目。

vals

您可以使用(vals (group-by first items)) => ([[:k1 0] [:k1 1]] [[:k2 2]])

放弃密钥
 (([:k1 0] [:k1 1]) ([:k2 2])) 

这与您的解决方案略有不同

 ([[:k1 0] [:k1 1]] [[:k2 2]]))

VS

(map #(into () %) result)

如果那很重要:

(defn list-of-equals [items]
    (->> (vals (group-by first items))
         (map #(into () %))))

最终解决方案如下:

if if if = then then then = else else else = if then ...