2013-05-01 4 views
2

У меня есть список карт, и один из ключей на карте - это ключ, который может повториться. Я хотел бы дедуплировать/объединить список. Так, например:merge-with merge: можно ли это упростить?

(def data [{:id 1 :a 2 :b 3 :c 4} {:id 1 :c 5 :d 6} {:id 2 :a 100 :b 101 :c 102} {:id 2 :a 103 :d 104} {:id 2 :a 200 :f 201}]) 

И я хотел бы, чтобы в итоге:

[{:id 1 :a 2 :b 3 :c 5 :d 6} {:id 2 :a 200 :b 101 :c 102 :d 104 :f 201}] 

(я сформулировал вопрос так, что слияния/слияния-с работы, но на самом деле, я дон 't действительно заботится о том, что происходит с перекрывающимися значениями, первая в или последняя в может победить).

Что у меня есть:

(vals (apply merge-with merge (into #(hash-map (:id %) %) data))) 

Который делает работу, но мне интересно, если есть лучше, consise, или элегантный, способ сделать это. Также мне интересно о производительности, потому что я думаю, что into выполняет полную копию последовательности и заставляет всю вещь в памяти (исходные данные были ленивой последовательностью).

+0

Существуют ли какие-либо гарантии на 'данные'? Знаем ли мы, что все карты с одним и тем же: id будут отображаться вместе? (Если вы не можете этого гарантировать, то это невозможно * лениво!) –

+1

да, они будут смежными. Они являются результатом набора запросов к базе данных. – Kevin

ответ

2

Если вы точно знаете, что карты с одинаковыми :id всегда будут непрерывными, вы можете использовать partition-by для создания подпоследовательности данных по идентификатору и объединить эти подпоследовательности:

(map (partial apply merge) (partition-by :id data)) 

Это будет ленивым и последним -Ин выиграет.

+0

это потрясающе. У меня есть еще один вопрос: скажем, карта имеет перекрывающиеся ключи, но иногда значение равно nil (и я хочу взять первое (или последнее) значение, отличное от нуля)? Я могу задать отдельный вопрос, если это имеет смысл. – Kevin

+0

nm ... 'merge-with' может легко сделать это. Еще раз спасибо! – Kevin

+0

Да, 'merge-with' с функцией слияния, например'% (if (nil?% 2)% 1% 2) '. –

Смежные вопросы