clojure 提高过滤二维列表的可读性
clojure improve readability of filter a two-dimensional list
当前代码采用如下输入:
[[: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 操作,我们可以一次收集具有相同键的所有项目。
(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 () %))))
当前代码采用如下输入:
[[: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 操作,我们可以一次收集具有相同键的所有项目。
(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 () %))))