考虑以下代码
(def values [[1 2] [3 4] [5] [6 7] [8]])
(apply max-key count values)
; => [6 7]
它返回的是最后一个最大的条目 [6 7]。为什么不是第一个最大的条目 [1 2]呢?
实际上,“max-key”并不保证返回哪个最大的值。
考虑以下Scala中的示例
println(List(List(0, 1, 2), List(2, 3, 4), List(1), List(1, 2, 3)).maxBy(_.length))
> List(0, 1, 2)
Scala中相同的函数返回的是第一个最大的条目(默认行为)。
从版本1.4的文件 "clojure/core.clj#4419-4426" 中的代码如下
=======================
4419: (defn max-key
4420: "返回(k x)最大的x,其中k x是一个数字。"
4421: {:added "1.0"
4422: :static true}
4423: ([k x] x)
4424: ([k x y] (if (> (k x) (k y)) x y))
4425: ([k x y & more]
4426: (reduce1 #(max-key k %1 %2) (max-key k x y) more)))
=======================
我不确定返回最后一个候选者的动机是什么,但我建议以下两点
1. 让 "max-key" 和 "min-key" 在有多个候选者时返回第一个最大/最小条目。
这种行为对我来说似乎更自然/方便,因为在大多数情况下,您想要获取第一个“赢家”。
(例如,找到序列中的第一个最大向量)而且很少需要获取最后一个条目——在这种情况下
您可以在向 "max-key" 提供序列之前进行“反转”,因此具有“返回第一个最大值”的行为似乎更有用。
行 #4424 应该使用 ">=" 而不是 ">"。
行 #4420 应该说“返回(k x)最大的x,其中k x是一个数字。如果有多个匹配项,将返回第一个最大条目”或同样的文档,但说“将返回最后一个最大条目”。
2. 让 "max-key" 和 "min-key" 对顺序做出保证,即返回哪个最大/最小条目(第一个或最后一个)。
行 #4420 应该说“返回(k x)最大的x,其中k x是一个数字。如果有多个匹配项,返回第一个最大条目”或同样的文档,但说“返回最后一个最大条目”。