在Clojure中 - 如何访问结构向量中的键

时间:2010-06-08 03:31:21

标签: 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))

有没有办法在没有将“get-price”函数映射到向量的情况下执行此操作?或者是否存在解决此问题的惯用方法?

1 个答案:

答案 0 :(得分:6)

很高兴看到与Clojure 101相关的问题! : - )

您可以在:price之间映射best-sellers;就这个代码惯用的程度而言,它可能不会产生太大的影响。在更复杂的场景中,使用get-price之类的东西可能是更好的风格并有助于维护。

至于可能对代码进行更深刻的更改,这实际上是编写代码的最简洁方法。另一种方法是编写自定义缩减功能:

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

这基本上将mapreduce合并在一起;偶尔这是有用的,但一般来说,将序列转换为单独的,明确定义的步骤有助于提高可读性和安全性。可维护性,应该是默认的方式。类似的评论适用于我想到的所有其他替代方案(包括loop / recur)。

总而言之,我会说你已经钉了它。这里没有调整。 : - )