我有一个像这样的字符串集合
["snowy10" "catty20" "manny20" "snowy20" "catty10" "snowy20" "catty30" "manny10" "snowy20" "manny30"]
Run Code Online (Sandbox Code Playgroud)
希望将其转换为基于字符串的前五个字符分组的集合的集合。
[["snowy10" "snowy20" "snowy20"] ["catty10" "catty20""catty30"]["manny10" ""manny20"" "manny20"]]
Run Code Online (Sandbox Code Playgroud)
在Clojure中寻找解决方案。
该group-by功能在这里很有帮助:
Run Code Online (Sandbox Code Playgroud)clojure.core/group-by ([f coll]) Returns a map of the elements of coll keyed by the result of f on each element. The value at each key will be a vector of the corresponding elements, in the order they appeared in coll.
换句话说,group-by使用给定的函数f为中的每个元素生成一个键coll,并且与该键关联的值是该键的累积元素向量。
在您的示例中,如果我们知道所有输入字符串都必须至少包含5个字符,则可以使用subs。但是使用take以下方法构建更通用的健壮解决方案更加容易:
clojure.core/group-by
([f coll])
Returns a map of the elements of coll keyed by the result of
f on each element. The value at each key will be a vector of the
corresponding elements, in the order they appeared in coll.
Run Code Online (Sandbox Code Playgroud)
给我们:
{(\s \n \o \w \y) ["snowy10" "snowy20" "snowy20" "snowy20"]
(\c \a \t \t \y) ["catty20" "catty10" "catty30"]
(\m \a \n \n \y) ["manny20" "manny10" "manny30"]}
Run Code Online (Sandbox Code Playgroud)
这不是我们想要的,我们只想要地图值。为此,我们使用vals:
(def strings ["snowy10" "catty20" "manny20" "snowy20" "catty10" "snowy20" "catty30" "manny10" "snowy20" "manny30"])
(group-by (partial take 5) strings)
Run Code Online (Sandbox Code Playgroud)
我们得到:
(["snowy10" "snowy20" "snowy20" "snowy20"]
["catty20" "catty10" "catty30"]
["manny20" "manny10" "manny30"])
Run Code Online (Sandbox Code Playgroud)
更改分组条件就像更改我们提供的“键”功能一样简单group-by。例如,我们可以使用take-last以下命令将每个字符串的最后两个字符分组:
{(\s \n \o \w \y) ["snowy10" "snowy20" "snowy20" "snowy20"]
(\c \a \t \t \y) ["catty20" "catty10" "catty30"]
(\m \a \n \n \y) ["manny20" "manny10" "manny30"]}
Run Code Online (Sandbox Code Playgroud)
这使:
(["snowy10" "catty10" "manny10"]
["catty20" "manny20" "snowy20" "snowy20" "snowy20"]
["catty30" "manny30"])
Run Code Online (Sandbox Code Playgroud)