假设有一个类似如下的序列:
["ab" "ba" "ac" "ca" "bc" "cc"]我想知道频率,但关键字应该是排序字符串。简而言之,我希望得到这样的结果:
{"ab" 2, "ac" 2, "bc" 1, "cc" 1}Clojure有frequencies函数,但它不接受key函数。因此,通常我可以通过结合使用group-by和map来实现这一点
(->> ["ab" "ba" "ac" "ca" "bc" "cc"]
(group-by #(apply str (sort %)))
(map (fn [[k vs]] [k (count vs)]))
(int {}))但是,这看起来很冗长。即使在Java语言中,我也可以使用Stream API同时进行分组和计数,如下所示:(假设有一个方法sortedStr(s)
Arrays.asList("aa", "ab", "ab", "bb", "cc" , "ca")
.stream()
.collect(groupingBy(s->sortedStr(s), counting()));在clojure中有没有像Java8那样一次分组和计数的方法?
发布于 2016-08-11 18:30:19
@Stefan answer工作得很好,但它并不是最有效的,因为它首先在coll上映射(产生一个中间集合),然后找到频率。所以它并不真正符合你问题中的"group-by和一次计数“部分。我宁愿选择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}发布于 2016-08-11 06:27:59
下面是一个使用内置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版本同时被更正了,所以我的最后一条评论变得过时了。
https://stackoverflow.com/questions/38884410
复制相似问题