文字列のリスト fx '("abc" "def" "gih") があり、リストから fx "ef" を含むアイテムを検索し、アイテムまたはインデックスを取得できるようにしたいと考えています。
これはどのように行われますか?
文字列のリスト 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"])
次に、各リストメンバーfilter
の要素に対して正規表現を使用できます。second
#(re-find #"ef" (second %))
以下は、インデックスを返す従来の再帰的な定義です。対応する文字列を返すように変更するのも簡単です。
(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 が返されます。)