有什么方法可以在Clojure中进行分组并立即计数吗?

时间:2016-08-10 22:12:45

标签: clojure

假设有如下序列:

svg

我想知道频率,但键应该是字符串排序。简而言之,我想得到这样的结果:

["ab" "ba" "ac" "ca" "bc" "cc"]

Clojure具有{"ab" 2, "ac" 2, "bc" 1, "cc" 1} 功能,但它不接受关键功能。 因此,通常我可以通过frequenciesgroup-by

的组合来完成此操作
map

但是,这看起来很冗长。即使在Java中,我也可以使用Stream API同时进行分组和计数,如下所示:(假设有一个方法(->> ["ab" "ba" "ac" "ca" "bc" "cc"] (group-by #(apply str (sort %))) (map (fn [[k vs]] [k (count vs)])) (int {}))

sortedStr(s)

有没有办法在像Java8这样的clojure中进行分组和计数?

2 个答案:

答案 0 :(得分:7)

这是使用内置frequencies函数的Clojure版本。

 (frequencies (map #(apply str (sort %)) 
                   ["ab" "ba" "ac" "ca" "bc" "cc"]))
 ;;=> {"ab" 2, "ac" 2, "bc" 1, "cc" 1}

我可能错了,但Java版本已经在您的示例中获取了排序键。在这种情况下,只需在Clojure中调用frequencies(如果我理解你的问题)。

编辑:在此期间看起来Java版本已得到纠正,因此我的上一条评论已经过时。

答案 1 :(得分:4)

@Stefan答案效果很好,但效率不高,因为它首先映射在coll上(产生一个中间集合),然后查找频率。所以它并不真正符合你的问题的“分组和计数”部分。我宁愿选择reduce

user> (reduce #(update %1 (apply str (sort %2)) (fnil inc 0))
              {} ["ab" "ba" "ac" "ca" "bc" "cc"])
{"ab" 2, "ac" 2, "bc" 1, "cc" 1}