В Clojure, как мне отсортировать набор карт по ключу внутри значения?

#clojure

#clojure

Вопрос:

Это неудобный вопрос для выражения, но, скажем, у меня есть набор таких карт:

 (def person-1 {:name "Joshua" :birthday {:day 5 :month 12 :year 1960}})
(def person-2 {:name "Louise" :birthday {:day 17 :month 4 :year 1987}})
(def person-3 {:name "Jessica" :birthday {:day 28 :month 5 :year 1972}})

(def people #{person-1 person-2 person-3})
 

Как бы я отсортировал people , например, по месяцу их рождения?

Я знаю (sort-by :name people) , что я мог бы просто выполнить сортировку по имени, но я не уверен синтаксически, как будет работать приведенный выше пример.

Комментарии:

1. Месяц рождения Джессики должен быть 5 , а не :5 . Исправлено.

Ответ №1:

Попробуйте:

 (sort-by (comp :year :birthday) people)
 

это сортируется по году рождения человека.


comp принимает список функций и объединяет их в единую функцию, которая сначала принимает параметр, сначала запускает функцию справа, получает результат, а затем переходит влево.

Подробности см. comp в ClojureDocs .

Ответ №2:

сортировка по принимает функцию в качестве первого аргумента, поэтому вы можете сделать:

 (sort-by (fn [m] (-> m :birthday :month)) people)
 

Комментарии:

1. Это немного быстрее, чем comp из-за макрорасширения при создании анонимного класса (хотя и не намного)

Ответ №3:

Другой вариант — использовать анонимную функцию:

 (sort-by #(:year (:birthday %)) people)
 

Делитесь и наслаждайтесь.