Улучшить функцию clojure - PullRequest
       0

Улучшить функцию clojure

0 голосов
/ 25 октября 2018

У меня есть однородный список карт, например:

({:x 1 :y 2} {:x 3 :y 5} {:x 1 :y 7} {:x 2 :y 0} {:x 3 :y -1})

Я хотел бы суммировать :y значения пар с равными :x значениями.Я имею в виду, я хочу функцию y-adder, которая при применении к предыдущему списку дает список (порядок не имеет значения, это может быть набор вместо списка)

({:x 1 :y 9} {:x 3 :y 4} {:x 2 :y 0})

То, что я написалвыглядит следующим образом:

(defn y-adder [Ps]
  (let [xs (set (map :x Ps))]
   (let [y+ (fn [v] (apply + (map :y (filter #(= (:x %) v) Ps))))]
    (map #(hash-map :x % :y (y+ %)) xs))))

Это работает, но кажется слишком сложным для такой простой задачи.Поэтому мне интересно, есть ли более простое (и, возможно, более эффективное) решение.

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Вы можете использовать group-by:

(defn y-adder [ps]
  (map (fn [[x-val matches]]
         {:x x-val :y (apply + (map :y matches))})
       (group-by :x ps)))
0 голосов
/ 25 октября 2018

Для меня это немного проще, но я не проверил, эффективнее ли это.

> (for [[k v] (group-by :x xs)] {:x k :y (apply + (map :y v))})
({:x 1, :y 9} {:x 3, :y 4} {:x 2, :y 0})

Ключ group-by:

> (group-by :x xs)
{1 [{:x 1, :y 2} {:x 1, :y 7}],
 3 [{:x 3, :y 5} {:x 3, :y -1}],
 2 [{:x 2, :y 0}]}

Как только вы это сделаете, это короткое путешествие к желаемому результату.

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