Как получить ключ в карте, значение которой содержит конкретную подстроку в clojure? - PullRequest
0 голосов
/ 09 сентября 2018

мне нужно получить ключ, значение которого содержит строку «TRY»

:CAB "NAB/TRY/FIGHT.jar"

, поэтому в этом случае вывод должен быть : CAB .

Я новичок в Clojure, я пробовал несколько вещей, таких как .contains и т. Д., Но я не мог сформировать точную функцию для вышеуказанной проблемы. Это проще в некоторых других языках, таких как python, но я не знаю, как это сделать в Clojure.

Есть ли способ получить имя ключа?

Ответы [ 4 ]

0 голосов
/ 09 сентября 2018

Во-первых, использование .contains не рекомендуется - во-первых, вы используете внутренние компоненты базового языка (Java или JavaScript) без необходимости, а во-вторых, это заставляет Clojure сделать отражение, поскольку он не может быть уверен, что аргументявляется строкой.

Вместо нее лучше использовать clojure.string/includes?.

Здесь уже было предложено несколько рабочих решений для извлечения ключа в зависимости от значения, вот еще одно, которое используетkeep функция:

(require '[clojure.string :as cs])

(keep (fn [[k v]] (when (cs/includes? v "TRY") k))
      {:CAB "NAB/TRY/FIGHT.jar" :BLAH "NOWAY.jar"})  ; => (:CAB)
0 голосов
/ 09 сентября 2018

Вы можете использовать некоторые из своей коллекции, some будет работать с каждым значением на вашей карте данной функцией, пока функция не вернет ненулевое значение.

Мы будем использовать функцию

(fn [[key value]] (when (.contains values "TRY") key))

when возвращает nil, если условие не соответствует, поэтому оно отлично подойдет для нашего варианта использования. Мы используем деструктуризацию в аргументах функции, чтобы получить ключ и значение. Когда кто-то его использует, ваша коллекция действительно будет преобразована в столбец, который будет выглядеть как

'((:BAR "NAB/TRY/FIGHT.jar"))

Если ваша карта называется coll, следующий код сделает это

(some
  (fn [[key value]] (when (.contains value "TRY") key)) 
  coll)
0 голосов
/ 09 сентября 2018

for также может фильтровать с :when. Э.Г.

(for [[k v] {:FOO "TRY" :BAR "BAZ"} 
      :when (.contains v "TRY")] 
        k)
0 голосов
/ 09 сентября 2018

Самый простой способ - использовать метод содержимого из java.lang.String. Я бы использовал это, чтобы отобразить действительные ключи, а затем отфильтровать, чтобы удалить все значения nil:

(filter some? 
        (map (fn [[k v]] (when (.contains v "TRY") k)) 
             {:CAB "NAB/TRY/FIGHT.jar" :BLAH "NOWAY.jar"}))
=> (:CAB)

Если вы считаете, что на карте есть не более одной такой совпадающей пары k / v, вы можете просто позвонить first, чтобы получить соответствующий ключ.

Вы также можете использовать регулярное выражение вместо .contains, например,

(fn [[k v]] (when (re-find #"TRY" v) k))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...