我有一个字符串列表,fx '("abc" "def" "gih"),我希望能够在列表中搜索包含fx "ef"的任何项目并获取返回的项目或索引。
这是怎么做到的?
结合filter
和re-find
可以很好地做到这一点。
user> (def fx '("abc" "def" "gih"))
#'user/fx
user> (filter (partial re-find #"ef") fx)
("def")
user> (filter (partial re-find #"a") fx)
("abc")
在这种情况下,我喜欢将它们与partial
结合起来,尽管在这种情况下定义匿名函数也可以正常工作。如果您事先不知道搜索字符串,使用 re-pattern
也很有用:
user> (filter (partial re-find (re-pattern "a")) fx)
("abc")
如果你想检索匹配位置的所有索引以及元素,你可以试试这个:
(filter #(re-find #"ef" (second %)) (map-indexed vector '("abc" "def" "gih")))
=>([1 "def"])
map-indexed vector
生成索引/值延迟序列
user> (map-indexed vector '("abc" "def" "gih"))
([0 "abc"] [1 "def"] [2 "gih"])
然后,您可以对每个列表成员的 second
元素使用正则表达式来filter
。
#(re-find #"ef" (second %))
只是索引:
-
懒洋洋 地:
(keep-indexed #(if (re-find #"ef" %2) %1) '("abc" "def" "gih")) => (1)
-
使用循环/重复
(loop [[str & strs] '("abc" "def" "gih") idx 0 acc []] (if str (recur strs (inc idx) (cond-> acc (re-find #"ef" str) (conj idx))) acc))
有关元素,请参阅Arthur Ulfeldts的答案。
下面是返回索引的传统递归定义。 修改以返回相应的字符串也很容易。
(defn strs-index [re lis]
(let [f (fn [ls n]
(cond
(empty? ls) nil
(re-find re (first ls)) n
:else (recur (rest ls) (inc n))))]
(f lis 0)))
user=> (strs-index #"de" ["abc" "def" "gih"])
1
user=> (strs-index #"ih" ["abc" "def" "gih"])
2
user=> (strs-index #"xy" ["abc" "def" "gih"])
nil
(说明:帮助程序函数f
在 let
中定义为绑定,然后在末尾调用。 如果传递给它的字符串序列不为空,它将在序列的第一个元素中搜索正则表达式,如果找到字符串,则返回索引。 这利用了这样一个事实,即 re-find
的结果除非失败,否则将计为 true,在这种情况下,它返回 nil
。 如果前面的步骤不成功,函数将使用序列的其余部分和递增的索引重新开始。 如果它到达序列的末尾,则返回 nil。