【问题标题】:Clojure: summing values in a collection of maps until a value is reached.Clojure:对一组映射中的值求和,直到达到一个值。
【发布时间】:2016-02-02 00:04:17
【问题描述】:

我的目标是将一组地图中的值相加,直到在其中一个地图值中达到一个值。我尝试使用this example 弄清楚它,但它没有涉及我如何只能获取列表的一部分。然后返回没有超过的值的集合。像这样的

(def foo '({:key 1, :value 2} {:key 1, :value 2} {:key 1, :value 2})
(defn addValuesUp [foo]
  (take-while (< ((apply merge-with + foo) :value) 4) foo))
 and have it return something like this
'({:key 1, :value 2} {:key 1, :value 2})   

相反,我得到一个错误 Boolean cannot be cast to clojure.lang.IFn

【问题讨论】:

    标签: collections clojure maps


    【解决方案1】:

    我解决问题的方法是向映射中添加一个新键,其中包含所有先前值的累积,这样您就可以做一个简单的花点时间:

    (defn sums-of-values [c]
      (reductions + c))
    
    (defn with-accum [c]
      (map #(assoc %1 :accum %2)
           c
           (sums-of-values (map :value c))))
    

    现在地图有一个 :accum 槽,你可以使用 take-while:

    (take-while (comp (partial >= 4)
                      :accum)
                (with-accum foo))
    

    【讨论】:

    • 谢谢你这对我有用我还添加了另一个包含 (apply merge-with + foo) 的函数,它添加了所有值
    • 请注意,take-while 中的最后一个值已经在 :accum 槽中包含总数
    【解决方案2】:

    查看take-while 的文档:

    clojure.core/take-while
    ([pred coll])
      Returns a lazy sequence of successive items from coll while
      (pred item) returns true. pred must be free of side-effects.
    

    pred 在这种情况下是一个返回布尔值的函数。在您的代码中,take-while 的第一个参数不是函数,而是表达式。

    这就是您收到错误ClassCastException java.lang.Boolean cannot be cast to clojure.lang.IFn 的原因。这个错误告诉你 Clojure 需要一个函数 (IFn) 但它找到了一个布尔值(你的表达式的结果)。

    一旦你把它变成一个函数,你就应该取得进步。然而,在函数实现中可能需要做更多的工作。

    【讨论】:

    • 这对我来说很有意义,但我不知道如何创建一个函数,该函数将使用 take-while 函数进行迭代以返回一个布尔值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-05
    • 2020-11-13
    • 1970-01-01
    • 1970-01-01
    • 2021-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多