Вот еще одна возможность, использующая естественно рекурсивный характер JSON.stringify
:
const input = [{"Attr":[{"power":{"p1":"str","t3":"str"},"light":[{"test":"str"},{"test2":[{"t4":"str"}]}]}]},{"Attr1":[{"power1":{"p2":"str","t5":"str"},"light1":[{"test3":"str"},{"test_x":[{"t_x":"str"},{"t_y":[{"t_y1":"str"}]}]}]}]}];
const output = [];
JSON.stringify(input, (key, val) => {
if (val === 'str') output.push(key);
return val;
});
console.log(output);
Просто немного соответствия шаблону ...
(require '[meander.match.alpha :as pm])
(letfn [(lookup [KEY LIST]
(pm/find LIST
(_ ... (~KEY ?v) . _ ...) ?v))]
(let [LIST '(((a b) 1) (c 2) (b 3))]
[(lookup 'b LIST)
(lookup '(a b) LIST)
(lookup 'd LIST)]))
=> [3 1 nil]
Это слишком много для такого простого случая, но он здесь, чтобы дать подсказку для некоторых более сложных вариантов использования.
(defn lookup [x xs]
(first (for [[k v] xs :when (= k x)]
v)))
Вот простая версия, которая работает:
(defn lookup
[k lol]
(let [the-map (into {}
(for [lst lol]
{(first lst) (second lst) } ))
result (get the-map k)]
result ) )
(lookup (quote b) (quote (((a b) 1) (c 2) (b 3)))) => 3
(lookup (quote [a b]) (quote (((a b) 1) (c 2) (b 3)))) => 1
(lookup (quote d) (quote (((a b) 1) (c 2) (b 3)))) => nil
Однако ваш код будет проще, если вы замените все цитируемые списки, такие как '(1 2 3)
, на векторы, подобные [1 2 3]
(don тогда не нужно использовать начальную кавычку) и заменить все символы в кавычках, например 'a
, на ключевые слова, подобные :a
(также не нужно заключать в кавычки символы.
Внесение этих изменений и добавление модульных тестов выглядит следующим образом Итак:
(ns tst.demo.core
(:use tupelo.core demo.core tupelo.test) )
(defn lookup
[k lol]
(get (into {} lol) k))
(dotest
(is= 3 (lookup :b [[[:a :b] 1] [:c 2] [:b 3]]))
(is= 1 (lookup [:a :b] [[[:a :b] 1] [:c 2] [:b 3]]))
(is= nil (lookup :d [[[:a :b] 1] [:c 2] [:b 3]])))
PS Пожалуйста, см. Brave Clojure для более подробной информации.
Обновление:
[ 1122] Нельзя использовать обычную функцию с этим синтаксисом:
(look-up b '(((a b) 1) (c 2) (b 3)))
, поскольку b
является символом и подразумевается как переменная , а не как часть данных .Вы можете выбрать:
b
в ключевое слово :b
, как я предлагал 'b
(болезненный и ошибочный -prone) lookup
(много работы за небольшую выгоду). Таким образом, я предложил пункт (1) в качестве предпочтительного решения.
Вы хотите найти первый объект в списке, который соответствует некоторым критериям (проверьте первый элемент объекта), затем Вы хотите сделать что-то к тому объекту (получите его второй элемент).
Clojure cheatsheet рекомендует some
или filter
для поиска seq.
(defn lookup
[x col]
(some (fn [[k v]]
(when (= x k) v))
col))
(defn lookup
[x col]
(->> col
(filter (fn [[k v]]
(when (= x k) v)))
first))
Также хороший вариант. См. ответ amalloy .
, Вы могли бы использовать любой из вышеупомянутых методов, чтобы сделать это.
(defn lookup
[pred f col]
(some (fn [x]
(when (pred x)
(f x)))
col))
(defn lookup
[pred f col]
(first (for [x col :when (pred x)]
(f x))))
;; usage: (lookup (comp '#{b} first) second data)