Confusion
Confusion

Reputation: 16841

Is there a standard way to compare Clojure vectors in the 'conventional' way

Clojure vectors have the uncommon property that when you compare them, the length of the vector is considered before any other property. In e.g. Haskell

Prelude> [1, 3] > [1, 2, 3]
True

and Ruby

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

But in Clojure:

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

Now you can implement the 'conventional' comparison yourself:

(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))))

but I expect this way of comparing vectors is so common that there is a standard way to achieve this. Is there?

Upvotes: 4

Views: 747

Answers (2)

Ankur
Ankur

Reputation: 33637

The compare function compares 2 things if they implement interface java.lang.Comparable. Vector in Clojure implement this interface as shown at this link, basically it check the length first. There is no core function which does what you want so you will have to roll your own function.

Other thing I would like to mention is that the haskell version is basically comparing lists (not vector) and it is not efficient to calculate list length which make sense to avoid length while comparing lists where as vector length calculation is O(1) operation and hence it make sense to check the length first.

Upvotes: 3

noahlz
noahlz

Reputation: 10311

Something like this?

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

Upvotes: 3

Related Questions