Clojure уменьшить функцию - PullRequest
0 голосов
/ 19 мая 2018

Я пытаюсь понять эту функцию из clojuredocs.org:

;; Create a word frequency map out of a large string s.

;; `s` is a long string containing a lot of words :)
(reduce #(assoc %1 %2 (inc (%1 %2 0)))
    {}
    (re-seq #"\w+" s))

; (This can also be done using the `frequencies` function.)

Я не понимаю эту часть: (inc (% 1% 2 0))

Ответы [ 3 ]

0 голосов
/ 19 мая 2018

Вот более простой пример того же, без использования синтаксиса анонимной функции:

(reduce
  (fn [acc elem]
    (assoc acc elem (inc (acc elem 0))))
  {}
  (re-seq #"\w+" "a dog a cat a dog a banana"))
=> {"a" 4, "dog" 2, "cat" 1, "banana" 1}

Здесь acc - карта, которую мы строим, а elem - текущее слово.Давайте разберемся (inc (acc elem 0)):

  1. inc будет увеличивать число, возвращаемое внутренним выражением
  2. (acc elem 0) собирается get текущее число изacc карта для слова elem, и если там нет номера, он вернет 0.Это сокращенно для (get acc elem 0) - карты тоже являются функциями и ведут себя как функция get.

Вы также можете добиться того же эффекта, что и (assoc acc elem (inc (acc elem 0))) с (update acc elem (fnil inc 0)).

Та же логика применяется при замене функции Reduce анонимным синтаксисом с использованием пронумерованных аргументов.

0 голосов
/ 20 мая 2018

Код, о котором вы спрашиваете, по сути код стандартной frequencies функции с переходными процессами удалено:

(defn frequencies [coll]
   (reduce
     (fn [counts x] (assoc counts x (inc (get counts x 0))))
     {}
     coll))

This

0 голосов
/ 19 мая 2018

Первый аргумент (%1 в анонимной функции) функции, переданной в reduce, является аккумулятором, который изначально является пустой картой {}, передаваемой в качестве второго аргумента reduce.Карты - это функции, которые ищут значение для данной клавиши, возвращая необязательное значение по умолчанию, если ключ не найден, например,

({"word" 1} "word") = 1

и

({"word" 1} "other" 0) = 0

, поэтому

(%1 %2 0)

ищет счетчик текущего слова (второй аргумент функции сокращения) в карте аккумулятора, возвращая 0, если слово еще не было добавлено.inc увеличивает текущий счетчик, поэтому

#(assoc %1 %2 (inc (%1 %2 0))

увеличивает счетчик текущего слова в промежуточной карте или устанавливает его в 1, если это слово встречается впервые.

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