Assume that there is a sequence like below:
["ab" "ba" "ac" "ca" "bc" "cc"]
I want to know the frequencies but the key should be sorted string. In short, I want to get the result like this:
{"ab" 2, "ac" 2, "bc" 1, "cc" 1}
Clojure has frequencies
function, but it doesn't accept key function. So, usually I can do this by the combination of group-by
and map
:
(->> ["ab" "ba" "ac" "ca" "bc" "cc"]
(group-by #(apply str (sort %)))
(map (fn [[k vs]] [k (count vs)]))
(int {}))
But, this looks verbose. Even in Java, I can do grouping and counting at the same time with Stream API, like this: (Assuming that there is a method sortedStr(s)
Arrays.asList("aa", "ab", "ab", "bb", "cc" , "ca")
.stream()
.collect(groupingBy(s->sortedStr(s), counting()));
Is there any way to group-by and counting at once in clojure like Java8?
@Stefan answer works well, but it is not the most efficient, because it first maps over the coll (producing an intermediate collection) and then finds frequencies. So it doesn't really conform to "group-by and count at once" part of your question. I would rather go with 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}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加