Bfcm
Bfcm

Reputation: 2746

Last element of an Array in Clojure

Is there any simplier way to find the last element of an array in clojure except this function?

(fn [l] (if (empty? (rest l)) (first l) (recur (rest l))))

Upvotes: 1

Views: 1895

Answers (2)

A. Webb
A. Webb

Reputation: 26446

For vectors, use peek for constant time

 user=> (peek [1 2 3 4 5])
 5

For Java arrays,

user=> (let [a (to-array [1 2 3 4 5])] (aget a (dec (alength a))))
5

For a general collection, you can get the last item in linear time with last. It is defined similarly to what you have done.

user=> (source last)
(def
 ^{:arglists '([coll])
   :doc "Return the last item in coll, in linear time"
   :added "1.0"
   :static true}
 last (fn ^:static last [s]
        (if (next s)
          (recur (next s))
          (first s))))

Upvotes: 13

Pold
Pold

Reputation: 347

The simplest way is to use (last l) that works in linear time (http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/last)

Another possibility is to reverse your collection and take the first element: ((comp first reverse) l). But that's rather slow as reverse returns a non-lazy sequence. Note: comp returns a composition of its arguments (functions) (http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/comp)

You can also convert the collection to a vector first and then apply peek: ((comp peek vec) l). This should have a better performance.

Another one: determine the length of your collection and take the last element (#(nth % (dec (count %))) l).

These functions work for all collection types (e.g. vectors, lists, ...). There are no arrays per se in Clojure (except you want to use Java arrays).

Upvotes: 2

Related Questions