clojure提高二维列表的可读性

clojure提高二维列表的可读性,clojure,code-readability,Clojure,Code Readability,当前代码采用如下输入: 并在列表中组织具有相同关键字的项目: ([:k1 0][:k1 1])([:k2 2])) 下面的代码可以工作,但我觉得可以改进。嵌套的 map#(filter看起来很难看,我想我可以使用clojurefor函数,用一个优雅的代码生成相同的结果 如何提高可读性? (defn list-of-equals [itens] (let [get-key (fn [[k]] k) keys (->> itens (map get-key) dis

当前代码采用如下输入:

并在列表中组织具有相同关键字的项目:
([: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))

您面临的问题是,必须对每个不同的键在列表中进行迭代。如果要对
使用
,则可能会出现如下情况

(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]]}
您可以使用
VAL弃用钥匙

(vals (group-by first items))
    => ([[: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 () %))))

(VAL(按第一个ITEN分组))
嗯,这看起来是可读的。谢谢,如果我花点时间写一个完整的解释,解释为什么它会取代代码,我会说你的算法需要改进,因为它很复杂。在这种情况下,可读性是第二个问题。请注意,它需要遍历在
O(n²)中执行的每个不同键的整个序列
@noisesmith solution解决了这两个问题。仅供参考-clojure的
=
认为如果向量和列表的内容相等,那么它们是相等的。谢谢,我已经更新了答案,使其更加准确。
(defn list-of-equals [items]
    (->> (vals (group-by first items))
         (map #(into () %))))