Vector Clojure,比较整数向量:为什么;更长的;向量始终是“;“大”字;?有补救办法吗?

Vector Clojure,比较整数向量:为什么;更长的;向量始终是“;“大”字;?有补救办法吗?,vector,clojure,comparator,Vector,Clojure,Comparator,它的工作原理如下: pcc.core=> (compare [4] [2 2]) -1 pcc.core=> (compare [4 0] [2 2]) 1 我想要一个具有“字符串语义”的向量比较器: 有没有一个简单、好的方法来得到我想要的东西?也许是这样 (defn compare-like-strings [a b] (let [res (first (drop-while zero? (map compare a b)))] (if (nil? res)

它的工作原理如下:

pcc.core=> (compare [4] [2 2])
-1
pcc.core=> (compare [4 0] [2 2])
1
我想要一个具有“字符串语义”的向量比较器:

有没有一个简单、好的方法来得到我想要的东西?

也许是这样

(defn compare-like-strings [a b]
  (let [res (first (drop-while zero? (map compare a b)))]
    (if (nil? res)
      0
      res)))
其思想是进行两两比较,返回-1、0或1的seq,然后删除所有前导的0。第一个非零元素是第一个不同的元素。

可能是这样的

(defn compare-like-strings [a b]
  (let [res (first (drop-while zero? (map compare a b)))]
    (if (nil? res)
      0
      res)))

其思想是进行两两比较,返回-1、0或1的seq,然后删除所有前导的0。第一个非零元素是第一个不同的元素。

如果两个向量长度相同,则比较似乎有效,因此让我提供以下内容:

(defn compare-vectors
  [a b]
  (compare
    (reduce conj a (map #{} b))
    (reduce conj b (map #{} a))))
这基本上是在运行比较之前,根据需要使用尽可能多的
nil
s填充输入。我喜欢它的外观(它应该完全符合您的要求),但我不确定是否会向任何人推荐它


编辑:我可能不会-效率非常低。

如果两个向量的长度相同,则比较似乎有效,因此让我提供以下内容:

(defn compare-vectors
  [a b]
  (compare
    (reduce conj a (map #{} b))
    (reduce conj b (map #{} a))))
这基本上是在运行比较之前,根据需要使用尽可能多的
nil
s填充输入。我喜欢它的外观(它应该完全符合您的要求),但我不确定是否会向任何人推荐它

编辑:我可能不会-效率太低了。

怎么样:

(defn compare-like-strings [[x & xs] [y & ys]]
  (let [c (compare x y)]
    (if (and (zero? c) (or xs ys))
      (recur xs ys)
      c)))
那么:

(defn compare-like-strings [[x & xs] [y & ys]]
  (let [c (compare x y)]
    (if (and (zero? c) (or xs ys))
      (recur xs ys)
      c)))

为什么不使用
subvec

(defn compare-like-strings
  [vec1 vec2]
  (let [len (min (count vec1) (count vec2))]
    (compare (subvec vec1 0 len)
             (subvec vec2 0 len))))

为什么不使用
subvec

(defn compare-like-strings
  [vec1 vec2]
  (let [len (min (count vec1) (count vec2))]
    (compare (subvec vec1 0 len)
             (subvec vec2 0 len))))
到目前为止是

(defn cmpv-int
  "Compare vectors of integers using 'string semantics'"
  [vx vy]
  (let [res (first (drop-while zero? (map compare vx vy)))
        diffenence (- (count vx) (count vy))]
     (if res res diffenence)
    )
  )
基于费边方法。

到目前为止

(defn cmpv-int
  "Compare vectors of integers using 'string semantics'"
  [vx vy]
  (let [res (first (drop-while zero? (map compare vx vy)))
        diffenence (- (count vx) (count vy))]
     (if res res diffenence)
    )
  )

基于Fabian方法。

正如我在对Diego答案的评论中所说,我认为最没有创意的方法在这里是最好的:只需编写一个循环,列举所有案例,然后努力完成它。作为奖励,这种方法也适用于任意序列,可能是惰性的,因为我们不需要依赖任何特定于向量的技巧

(defn lexicographic-compare
  ([xs ys]
     (lexicographic-compare compare xs ys))
  ([compare xs ys]
     (loop [xs (seq xs) ys (seq ys)]
       (if xs
         (if ys
           (let [c (compare (first xs) (first ys))]
             (if (not (zero? c))
               c
               (recur (next xs), (next ys))))
           1)
         (if ys
           -1
           0)))))

正如我在对迭戈答案的评论中所说的,我认为最没有创意的方法在这里是最好的:只需编写一个循环,列举所有案例,然后努力完成它。作为奖励,这种方法也适用于任意序列,可能是惰性的,因为我们不需要依赖任何特定于向量的技巧

(defn lexicographic-compare
  ([xs ys]
     (lexicographic-compare compare xs ys))
  ([compare xs ys]
     (loop [xs (seq xs) ys (seq ys)]
       (if xs
         (if ys
           (let [c (compare (first xs) (first ys))]
             (if (not (zero? c))
               c
               (recur (next xs), (next ys))))
           1)
         (if ys
           -1
           0)))))


不要忘记所有元素都相同的情况-它应该产生0。此外,如果我们比较
[1 2]
[1 1 1]
,会怎么样?对,刚刚注意到并修复了两者相等的情况。我想
[1 1 2]
[1 1]
的情况取决于您的需求?我想是Alexey的电话。虽然代码很好,但长度上的改进是受欢迎的:)。[1]应该小于[1 2]不要忘记所有元素都相同的情况-它应该产生0。此外,如果我们比较
[1 2]
[1 1]
,会怎么样?对,只是注意到了这一点,并修复了两者相等的情况。我想
[1 1 2]
[1 1]
的情况取决于您的需求?我想是Alexey的电话。虽然代码很好,但长度上的改进是受欢迎的:)[11]应该小于[12]为什么这是“字符串语义”?我希望字符串比较具有与vector相同的行为(这至少是Clojure和Java的行为)。@AlexMiller,
(比较“abc”“ac”)
=>-1,但
(比较[1 2 3][1 3])
=>1。@AlexMiller字符串传统上是按字典进行比较的,Clojure和Java都继承了这一传统。不同的是,向量在内容之前比较长度,而字符串只有在前N项比较相同时才使用长度。啊,我明白你的意思。为什么这是“字符串语义”?我希望字符串比较具有与vector相同的行为(这至少是Clojure和Java的行为)。@AlexMiller,
(比较“abc”“ac”)
=>-1,但
(比较[1 2 3][1 3])
=>1。@AlexMiller字符串传统上是按字典进行比较的,Clojure和Java都继承了这一传统。不同之处在于向量在内容之前比较长度,而字符串仅在前N项比较相同时才使用长度。啊,我明白你的意思。这忽略了一些边缘情况,通过
xs
ys
上的nil双关以及检查空输入的失败。例如,
(与字符串[nil][])
返回0。@amalloy捕捉良好。最好将它们与普通的旧循环进行比较。如果您用完了一个,并且到目前为止它一直在匹配,则返回-1或1,具体取决于哪个用完了。我的经验法则基本上是永远不要使用
[x&xs]
解构。理论上这很吸引人,但实际上我总是想变得更懒,或者不能确定至少有一个元素,或者类似的东西,所以我最终使用了
seq
first
,和
next
rest
。我最后用
count
subvec
修复了它,但代码太难看了,无法发布。关于
[x&xs]
的优点是,在这种情况下,它是复合的,因为有两个序列。我同意在循环中进行比较是最好的:当你处理两个不同长度的序列时,最不具创造性和最乏味的解决方案胜过所有聪明的HOF方法。如果你小心的话,你可以使它适用于任意的序列和向量。这会错过一些边缘情况,通过
xs
ys
上的nil双关以及检查空输入的失败。例如,
(与字符串[nil][])
返回0。@amalloy捕捉良好。最好将它们与普通的旧循环进行比较。如果您用完了一个,并且到目前为止它一直在匹配,则返回-1或1,具体取决于哪个用完了。我的经验法则基本上是永远不要使用
[x&xs]
解构。这在理论上很吸引人,但在实践中我总是想变得更懒,或者不能确定至少有一个因素,或者