【问题标题】:Clojure reduce requires val parameter to accumulate vectorClojure reduce 需要 val 参数来累积向量
【发布时间】:2015-09-05 10:43:00
【问题描述】:

我正在做一个减少,我想累积并返回一个向量。这样做时效果很好:

(reduce
  (fn [[res-vec last-rgb] rgb]
    (let [calc-res (mu/colour-distance-L2 last-rgb rgb)
          accum-results (conj res-vec calc-res)]
      [accum-results rgb]))
  []
  colour-selections)

但是,当[] 参数被忽略时,我得到Caused by: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long。这是因为colour-distance-L2 被赋予了至少一个java.lang.Long 而不是它所期望的两个向量(type [r g b] 的两个向量 - 用于红色绿色和蓝色)。

This 正是我正在做的那种减少。

我不需要使用 3 元版本的 reduce,因为 colour-selections 的大小始终至少为 2。我只是将 [] 作为试错的一部分 em> 越过运行时错误。事实证明,这样做会产生很好的效果。

有什么方法可以在这里使用 2-arity 版本的 reduce 吗?

【问题讨论】:

  • I do not need to use the 3-arity version of reduce, because colour-selections will always have a size of at least 2. 我什至不知道是什么让你这么想。如果输入序列的第一个元素与累加器的类型不同,则需要 3 arity 版本。
  • 这是我的第一个 Clojure reduce。我习惯了 Scala 折叠,你总是有一个“种子”,所以以前从来没有真正用过这些术语。

标签: clojure


【解决方案1】:

您只能使用 2-arity reduce,前提是您的归约函数具有类似 (A,A) → A 的签名 - 获取两个相同类型的值并生成另一个该类型的值。
你的签名为 (A,B) → A,其中 A 是一对 [res-vec last-rgb]
B 是三元组[r g b]。如果你想在 B 的序列上减少它,提供第一个 A 来启动序列是必要的,因为该函数不知道如何将两个 B 变成一个 A。

话虽这么说,但我并不认为这里需要reduce。假设 res-vec 是您减少的有趣值,它也可以通过将颜色距离映射到 colour-selections 及其本身减去 1 个元素来产生。像

(mapv mu/colour-distance-L2 colour-selections (drop 1 colour-selections))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-06
    • 1970-01-01
    • 1970-01-01
    • 2015-05-05
    • 2020-11-12
    • 2021-07-13
    • 1970-01-01
    • 2017-06-28
    相关资源
    最近更新 更多