Clojure - Створіть масив ключів, якщо значення true

Я абсолютно новий для clojure.

I have a JSON like: { "1": true, "2": false, "3": true, "4": false }

Я хочу створити масив ключів, для яких значення clojure вірно. У цьому прикладі масив має бути ["1", "3"] .

Будь ласка, допоможи мені. Будь-яка допомога буде оцінена.

0
Це досить широке. Що ви пробували? Я б подивився на filter , а також для фільтрування з помилковим значенням.
додано Автор Carcigenicate, джерело
@jstuartmilne Здається, що вони хочуть ключі від пар з істинним значенням.
додано Автор Carcigenicate, джерело
Я не розумію питання. Ви маєте на увазі лише ключі?
додано Автор jstuartmilne, джерело
Ласкаво просимо до Clojure, я припускаю, що ви використовуєте data.json або cheshire для маршалювання json на карту Clojure. Після того, як ви зробите це, фільтрування карти за допомогою клавіш (перший приклад у відповіді leetwinski) працюватиме. Це пояснюється тим, що карти можуть розглядатися як функції, які приймає фільтр.
додано Автор Gary, джерело
Так, я хочу масив ключів з істинним значенням.
додано Автор Tessy Thomas, джерело

6 Відповіді

Є також кілька коротких і простих фрагментів для цього:

user> (filter m (keys m))
;;=> ("1" "3")

user> (keep (fn [[k v]] (when v k)) m)
;;=> ("1" "3")

user> (for [[k v] m :when v] k)
;;=> ("1" "3")
7
додано
Чудово! Це спрацювало. Дуже дякую.
додано Автор Tessy Thomas, джерело

Якщо ви маєте справу з використанням вектора замість масиву (оскільки ви зазвичай використовуєте вектори у Clojure), ви можете зробити щось подібне.

(defn keys-for-truthy-vals [m]
  (->> m (filter val) (mapv key)))

Note The mapv is only so the map call returns a vector. If you want a seq, just use map.

3
додано
key і val вже існують для повернення ключа і значення пари карт, тому прив'язки let не потрібні.
додано Автор Lee, джерело
@Lee спасибі! Я забув про це. Оновили відповідь
додано Автор Edward Minnix, джерело

У бібліотеці Tupelo вбудована функція :

(submap-by-vals map-arg keep-vals & opts)

Returns a new map containing entries with the specified vals. Throws for missing vals,
unless `:missing-ok` is specified. Usage:

(submap-by-vals {:a 1 :b 2 :A 1} #{1  }             )  =>  {:a 1 :A 1}
(submap-by-vals {:a 1 :b 2 :A 1} #{1 9} :missing-ok )  =>  {:a 1 :A 1} 

Ви можете просто скористатися функцією keys на отриманій карті.

0
додано

Можливо, це?

(->> foo (filter second) keys)

де foo - карта.

0
додано

If your map is a Something like (->> (filter (fn [[k v]] v) a) (map (fn [[k v]] k))) will work. You can't do it with just a map because you need to drop certain values, so there will need to be some reducing or filtering.

0
додано
Стиль бажання: якщо ви використовуєте потокові макроси, такі як ->> , витягніть "перший" аргумент також на перше місце. Напр. (- >> a (фільтр (,)) (map (,)))
додано Автор cfrick, джерело
Я спробував (- >> (фільтр (fn [[kv]] v) аромат-ids (карта (fn [[kv]] k))) Але я отримую помилку "Uncaught Error: Oops, відсутній очікуваний ключ об'єкта "дані" ".
додано Автор Tessy Thomas, джерело

Те ж, що вже передбачено, просто залишаючись на картах.

(клавіші (фільтр val m))

0
додано