Clojure код адаптирован из карте-инвертировать


Я хотел сделать следующее:

  • Подсчет частоты слов в тексте (более 5 букв)
  • Переверните карту слова частотах, но группировать слова, которые имеют одинаковую частоту в инверсии.
  • Сортировать перевернутой карте по ключам порядке убывания и взять топ 25.

Вот код, который я придумал. Я заново изобретать колесо с карте-инверт-сохранить-дубликатов? Есть ли более лаконичный способ сделать то, что я сделал? Я делаю что-то без надобности (т. е. (~к)?

(defn map-invert-preserve-dups
  [m]
  (reduce
    (fn [m [k v]]
      (if (contains? m v)
        (assoc m v (cons k (get m v)))
        (assoc m v `(~k))))
    {}
    m))

(->> "http://www.weeklyscript.com/Pulp%20Fiction.txt"
  (slurp)
  (re-seq #"\w{5,}")
  (frequencies)
  (map-invert-preserve-dups)
  (sort)
  (reverse)
  (take 25))


297
2
задан 10 декабря 2011 в 02:12 Источник Поделиться
Комментарии
1 ответ

Ну, наиболее очевидный исправить это действительно карта-инверт-консервирование-дубликатов - все это может быть более легко записать в виде:

(defn map-invert-preserving-dups [m]
(apply merge-with into
(for [[k v] m]
{v [k]})))

В для выражения получается последовательность карт, как [{А [1]} {Б [2]} {а [5]}]. Применить называет слиянием с В на все эти карты. Если вы посмотрите определение слияния-с, вы можете увидеть, что это означает по сути: "объединить все эти карты вместе, а если один и тот же ключ два раза, причем значения х и у, затем сделайте его стоимости (в Х г)".

5
ответ дан 10 декабря 2011 в 03:12 Источник Поделиться