В Clojure - Как получить доступ к ключам в векторе структур - PullRequest
5 голосов
/ 08 июня 2010

У меня есть следующий вектор структур:

(defstruct #^{:doc "Basic structure for book information."}
  book :title :authors :price)

(def #^{:doc "The top ten Amazon best sellers on 16 Mar 2010."}
  best-sellers
  [(struct book
           "The Big Short"
           ["Michael Lewis"]
           15.09)
   (struct book
           "The Help"
           ["Kathryn Stockett"]
           9.50)
   (struct book
           "Change Your Prain, Change Your Body"
           ["Daniel G. Amen M.D."]
           14.29)
   (struct book
           "Food Rules"
           ["Michael Pollan"]
           5.00)
   (struct book
           "Courage and Consequence"
           ["Karl Rove"]
           16.50)
   (struct book
           "A Patriot's History of the United States"
           ["Larry Schweikart","Michael Allen"]
           12.00)
   (struct book
           "The 48 Laws of Power"
           ["Robert Greene"]
           11.00)
   (struct book
           "The Five Thousand Year Leap"
           ["W. Cleon Skousen","James Michael Pratt","Carlos L Packard","Evan Frederickson"]
           10.97)
   (struct book
           "Chelsea Chelsea Bang Bang"
           ["Chelsea Handler"]
           14.03)
   (struct book
           "The Kind Diet"
           ["Alicia Silverstone","Neal D. Barnard M.D."]
           16.00)])

I would like to sum the prices of all the books in the vector.  What I have is the following:

(defn get-price
  "Same as print-book but handling multiple authors on a single book"
  [ {:keys [title authors price]} ]
   price)

Тогда я:

(reduce + (map get-price best-sellers))

Есть ли способ сделать это без сопоставления функции "get-price" свектор?Или есть идиоматический подход к этой проблеме?

1 Ответ

6 голосов
/ 08 июня 2010

Приятно видеть вопрос, связанный с Clojure 101! : -)

Вы можете отобразить :price через best-sellers; это, вероятно, не будет иметь большого значения для степени, в которой этот код является идиоматическим. В более сложных сценариях использование чего-то вроде get-price может быть лучшим стилем и облегчить поддержку.

Что касается возможных более глубоких изменений в коде, то это на самом деле самый чистый способ его написания. В качестве альтернативы можно написать пользовательскую функцию сокращения:

(reduce (fn [{price :price} result] (+ price result))
        0
        best-sellers)

Это в основном объединяет map и reduce вместе; иногда это полезно, но в целом разбиение преобразования последовательности на отдельные, четко определенные шаги помогает удобочитаемости и удобству обслуживания и должно быть способом по умолчанию. Подобные комментарии относятся ко всем другим альтернативам, которые приходят мне в голову (включая loop / recur).

В общем, я бы сказал, что ты это прибил. Здесь не нужно вносить никаких изменений. : -)

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