Удаление ключей и значений с карты - PullRequest
1 голос
/ 29 января 2020

У меня есть карта, которая выглядит следующим образом:

{\a [\h] 
 \h [\w \w]
 \i [\w \h \t]
 \p [\t \u \h \a]
 \s [\t \a \t \t \i \w \h]
 \t [\a]
 \u [\t \t \s]
 \w []}

Я хочу удалить, например, \ w как из ключей, так и из значений. т.е. оставляя это

{\a [\h] 
 \h []
 \i [\h \t]
 \p [\t \u \h \a]
 \s [\t \a \t \t \i \h]
 \t [\a]
 \u [\t \t \s]}

Обратите внимание, клавиша \ w ушла и \ w ушла от всех значений!

Прямо сейчас у меня есть это, которое работает, но я уверен должен быть лучший способ Clojurey!

(defn remove-last [last cmap]
  (reduce-kv (fn [acc k v]
               (if (empty? v)
                 acc
                 (into acc {k (vec (filter #(not= % last) v))}))) {} cmap))

Ключом для удаления всегда будет пустой вектор.

Как я могу сделать это лучше?

Ответы [ 3 ]

8 голосов
/ 30 января 2020

что я хотел бы предложить, это сначала отменить c ключ \ w от карты (учитывая, что это ~ операция с постоянным временем), а затем использовать преобразователь для изменения последовательности за один проход без потери декларативного стиля, и устранить многословие снижения, сохраняя при этом производительность. может выглядеть так:

(into {}
      (map (fn [[k v]] [k (filterv #(not= \w %) v)]))
      (dissoc data \w))

, что касается меня, я считаю, что это более читабельно, чем уменьшение / ассо c или уменьшение / обновление

4 голосов
/ 30 января 2020

Мне очень нравится призрак:

(s/setval (s/walker (fn-> (= \w))) s/NONE {\a [\h]
                                              \h [\w \w]
                                              \i [\w \h \t]
                                              \p [\t \u \h \a]
                                              \s [\t \a \t \t \i \w \h]
                                              \t [\a]
                                              \u [\t \t \s]
                                              \w []})
2 голосов
/ 29 января 2020

Я нахожу ваше решение довольно идиоматическим c. Требование достаточно необычное, что я сразу думаю reduce. Ваш звонок на empty? не соответствует вашим требованиям c. Вам нужно проверить, чтобы ключ k был = - last.

Кроме того, я бы не стал использовать здесь имя last. Это сталкивается с именем, которое уже присутствует.

Очень похожая альтернатива будет

(defn remove-all-of [it m] 
  (reduce
   (fn [acc [k v]] 
     (if (not= it k)
       (assoc acc
              k
              (into (empty v)
                    (filter #(not= it %) v)))
       acc))
   {}
   m))

Это также позволяет вам использовать в качестве значений некоторые другие секвенируемые объекты, отличные от векторов, используя (empty v).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...