当前代码接受如下输入:[[: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))
您面临的问题是,您必须对每个不同键的列表进行迭代。如果您使用for
,它可能看起来像这样。
(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]]))
如果这很重要:
(map #(into () %) result)
最终的解决方案看起来像:
(defn list-of-equals [items]
(->> (vals (group-by first items))
(map #(into () %))))