2010-06-08 3 views
5

Я следующий вектор структур:В Clojure - Как получить доступ ключи в векторе структур

(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)) 

Есть ли способ сделать это без отображения функция «получить цену» над вектором? Или существует идиоматический подход к решению этой проблемы?

+0

Ваш метод в значительной степени является идиоматическим способом решения этой проблемы. –

+0

'defstruct', вероятно, будет устаревшим/отмененным' defrecord'/'deftype', FYI. http://groups.google.com/group/clojure/msg/330c230e8dc857a9 –

ответ

6

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

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

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

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

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

В целом, я бы сказал, вы прибили его. Никаких хитростей здесь нет. :-)

+0

Благодарим вас за быстрый ответ Michal. – Nick

Смежные вопросы