当前代码采用如下输入:
[[: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))
答案 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 ...