Хобрук: Ваш путь к мастерству в программировании

Отсортируйте элементы этого списка по частоте их длины в Clojure.

(defn lfsort [list](mapcat  #(if (sequential? %) % [%]) 
                              (sort-by count (vals (group-by count list)))))

Сегодня на семинаре мы обсуждали приведенную выше функцию, которая, если задана, выводит (lfsort '((a b c) (d e) (f g h) (d e) (i j k l) (m n) (o))):

((i j k l)
 (o)
 (a b c)
 (f g h)
 (d e)
 (d e)
 (m n))

Мы начали с программирования функции, которая сортирует его по длине, используя

(defn sort [list] (sort-by count list))

вывод:

((o)
 (d e)
 (d e)
 (m n)
 (a b c)
 (f g h)
 (i j k l))

Я понимаю, как работает функция сортировки, но я все еще не уверен в том, как работает lfsort. Может ли кто-нибудь помочь мне разобраться?

Благодарю вас!

07.01.2017

Ответы:


1

Преимущество языка, в котором упор делается на интерактивное программирование в REPL, заключается в том, что вы можете очень легко экспериментировать со всеми маленькими частями, из которых состоит ваша функция.

Сначала определите list как ваши данные.

(def list '((a b c) (d e) (f g h) (d e) (i j k l) (m n) (o)))

Затем оцените формы в вашей функции lfsort (единственный аргумент которой удобно называть list). Начните с оценки самых внутренних форм, а затем постепенно расширяйтесь, пока не оцените все тело функции. Используйте doc для всех встроенных функций и экспериментируйте!

So:

(group-by count list)
; => {3 [(a b c) (f g h)], 2 [(d e) (d e) (m n)], 4 [(i j k l)], 1 [(o)]}

… теперь у нас есть карта подсчетов в списки размера «подсчет»…

(vals (group-by count list))
; => ([(a b c) (f g h)] [(d e) (d e) (m n)] [(i j k l)] [(o)])

… теперь у нас есть последовательность только значений карты (каждый из векторов значений содержит списки одинакового размера)…

(sort-by count (vals (group-by count list)))
; => ([(i j k l)] [(o)] [(a b c) (f g h)] [(d e) (d e) (m n)])

… теперь векторы в seq упорядочены по количеству списков в них…

(mapcat #(if (sequential? %) % [%])
  (sort-by count (vals (group-by count list))))
;; => ((i j k l) (o) (a b c) (f g h) (d e) (d e) (m n))

… наконец, списки распаковываются из векторов и сглаживаются в простую последовательность. Списки в последовательности теперь упорядочены, причем те списки, размеры которых встречаются реже всего, находятся впереди.

Между прочим, последнюю операцию mapcat можно было бы выразить проще с помощью (apply concat ,,,).

07.01.2017

2

Во-первых, мы можем упростить до

(defn lfsort [coll]
  (apply concat 
   (sort-by count (vals (group-by count coll)))))

... так как sequential? всегда возвращает true.

Мы можем переформулировать это как

(defn lfsort [coll]
  (->> coll
       (group-by count)
       vals
       (sort-by count)
       (apply concat)))

... используя макрос ->> thread-last.

Итак, эта функция

  • принимает свой аргумент coll,
  • группирует элементы своей коллекции по count,
  • отбрасывает ключи, отображая значения вектора,
  • сортирует эти векторы по длине и, наконец,
  • объединяет векторы.
07.01.2017
Новые материалы

Учебные заметки JavaScript Object Oriented Labs
Вот моя седьмая неделя обучения программированию. После ruby ​​и его фреймворка rails я начал изучать самый популярный язык интерфейса — javascript. В отличие от ruby, javascript — это более..

Разбор строк запроса в vue.js
Иногда вам нужно получить данные из строк запроса, в этой статье показано, как это сделать. В жизни каждого дизайнера/разработчика наступает момент, когда им необходимо беспрепятственно..

Предсказание моей следующей любимой книги 📚 Благодаря данным Goodreads и машинному обучению 👨‍💻
«Если вы не любите читать, значит, вы не нашли нужную книгу». - J.K. Роулинг Эта статья сильно отличается от тех, к которым вы, возможно, привыкли . Мне очень понравилось поработать над..

Основы принципов S.O.L.I.D, Javascript, Git и NoSQL
каковы принципы S.O.L.I.D? Принципы SOLID призваны помочь разработчикам создавать надежные, удобные в сопровождении приложения. мы видим пять ключевых принципов. Принципы SOLID были разработаны..

Как настроить Selenium в проекте Angular
Угловой | Селен Как настроить Selenium в проекте Angular Держите свое приложение Angular и тесты Selenium в одной рабочей области и запускайте их с помощью Mocha. В этой статье мы..

Аргументы прогрессивного улучшения почти всегда упускают суть
В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

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