我有一个字符串列表,例如:
("2019_FOO_BAR.1_12"
"2019_FOO_BAR.1_13"
"2018_FOO_BAR.1_12"
"2019_FOO_XYZ.1_14"
"2017_FOO_BAR.1_14"
"2017_FOO_XYZ.1_12"
"2019_FOO_XYZ.1_13")
我想在第一个下划线之后和点之前按公共子字符串对它们进行分组。
在此示例中,我有2个唯一的子字符串FOO_BAR和FOO_XYZ。但是较长的列表可能包含N个唯一的子字符串。
我希望结果看起来像这样:
(["2019_FOO_BAR.1_12" "2019_FOO_BAR.1_13" "2018_FOO_BAR.1_12" "2017_FOO_BAR.1_14"]
["2017_FOO_XYZ.1_12" "2019_FOO_XYZ.1_13" "2019_FOO_XYZ.1_14"])
因此每个子字符串都分组在一个单独的列表中
答案 0 :(得分:4)
我认为您正在寻找group-by
(def test-data '("2019_FOO_BAR.1_12"
"2019_FOO_BAR.1_13"
"2018_FOO_BAR.1_12"
"2019_FOO_XYZ.1_14"
"2017_FOO_BAR.1_14"
"2017_FOO_XYZ.1_12"
"2019_FOO_XYZ.1_13"))
(defn string-to-key [^String input-string]
(let [first-spliter (.indexOf input-string "_" )
second-spliter (.indexOf input-string "." )]
(.subSequence input-string (+ 1 first-spliter) second-spliter)))
因此,您可以获得所需的确切信息:
(vals (group-by string-to-key test-data))
答案 1 :(得分:4)
正则表达式的良好候选人:
user> (vals (group-by (partial re-find #"_.*?\.") data))
;; => (["2019_FOO_BAR.1_12"
;; "2019_FOO_BAR.1_13"
;; "2018_FOO_BAR.1_12"
;; "2017_FOO_BAR.1_14"]
;; ["2019_FOO_XYZ.1_14" "2017_FOO_XYZ.1_12" "2019_FOO_XYZ.1_13"])