有没有一种标准的方法来以“传统”的方式比较Clojure向量?

4
Clojure向量有一个不同寻常的特性,在比较它们时,向量的长度被优先考虑,而不是其他任何属性。例如在Haskell中则不然。
Prelude> [1, 3] > [1, 2, 3]
True

以及Ruby

1.9.3p392 :003 > [1, 3] <=> [1, 2, 3]
 => 1 

但在Clojure中:

user=> (compare [1, 3] [1, 2, 3])
-1

现在您可以自己实现“传统”的比较方法:
(defn vector-compare [[value1 & rest1] [value2 & rest2]]
  (let [result (compare value1 value2)]
    (cond 
      (not (= result 0)) result
      (nil? value1) 0 ; value2 will be nil as well 
      :else (recur rest1 rest2))))

但我预计比较向量的方法很常见,应该有一种标准的方法来实现这个功能,是吗?

2个回答

3
compare函数比较两个实现了接口java.lang.Comparable的对象。Clojure中的向量实现了这个接口,如链接所示,它首先检查长度。没有核心函数可以满足你的需求,因此你需要自己编写函数。
另外,我想提到的是,Haskell版本基本上是在比较列表(而不是向量),计算列表长度不是高效的操作,因此在比较列表时避免使用长度,而向量长度计算是O(1)操作,因此首先检查长度是有意义的。

3

像这样的内容?

(first (filter (complement zero?) (map compare [1 3] [1 2 3])))

不幸的是,对于大小不相等的向量(例如[1 2]和[1 2 3]),它不能返回预期的结果。在其他语言中(或至少在Haskell和Ruby中),当它们具有相等的前缀时,最长的向量将被认为更大。一个更短的版本很好,但我主要想知道核心或标准库中是否存在这样的版本。 - Confusion
可以的,但也许编写自己的函数时,可以利用我使用的一些核心函数。 - noahlz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接