2013-12-10 2 views
1

Следующие мелкие списки прекрасно подходят для небольших списков (< 500), но он висит неопределенно для больших списков (> 2500). Есть ли лучший способ добиться этого эффекта без сбоев?Оптимизация слияния с Clojure

(def errors '({:a-key 
    ["some string"]} 
    {:a-key 
    ["some string"]} 
    {:a-key 
    ["some string"]} 
    {:a-key 
    ["some other string"]})) 

(def unique-errors (apply merge-with (comp distinct into) errors)) 

;; => {:a-key ("some string", "some other string")} 

ответ

5

Основная проблема с кодом, я думаю, это не то, что это медленно, так, что это приводит к переполнению стека, потому что distinct вызывается один раз для каждой новой ошибки, и это лень, поэтому при печати В результате есть много «вложенных» вызовов distinct.

Но так или иначе: используйте наборы для вещей, которые не должны содержать дубликатов. Использование наборов приводит к следующему, что немного быстрее и не приводит к переполнению стека.

(def errors (repeat 5000 {:a-key #{"some string"}})) 
(apply merge-with into errors) 
+0

С исходной структурой данных '(apply merge-with in (set errors))'. –

+0

@ A.Webb только в том случае, если есть только один ключ или что дубликаты идут в руке (карты dupliacte против дубликатов записей). – cgrand

+0

Я принимал последнее, но вы правы, это не будет таким же, как решение OP. –

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