ClojureDocs

Nav

Namespaces

butlast

clojure.core

Available since 1.0 (source)
  • (butlast coll)
Return a seq of all but the last item in coll, in linear time
4 Examples
user=> (butlast [1 2 3])
(1 2)
user=> (butlast (butlast [1 2 3]))
(1)
user=> (butlast (butlast (butlast [1 2 3])))
nil
;really slow reverse
;put the last item of the list at the start of a new list, and recur over all but the last item of the list.
;butlast acts similar to next in that it returns null for a 1-item list.

(defn my-reverse [xs]
  (when xs
    (cons (last xs) (my-reverse (butlast xs)))))
;; A version of (into) that doesn't require (comp)
;; for transducers arguments.

(defn into* [to & args]
  (into to
    (apply comp (butlast args))
    (last args)))

(into* [] (range 10))
;; [0 1 2 3 4 5 6 7 8 9]

(into* [] (map inc) (range 10))
;; [1 2 3 4 5 6 7 8 9 10]

(into* [] (map inc) (filter odd?) (range 10))
;; [1 3 5 7 9]
;; `butlast` (linear time) vs. `drop-last` (lazy, efficient, more flexible, 
;; constant time(?)) vs. `pop` (fast but requires a vector).

(def r (range 10000))

(time (butlast r))       ;;=> "Elapsed time: 6.379 msecs"
(time (drop-last r))     ;;=> "Elapsed time: 0.0475 msecs"
(time (drop-last 2 r))   ;;=> "Elapsed time: 0.0569 msecs"
(time (drop-last 0 r))   ;;=> "Elapsed time: 0.098 msecs"
(time (drop-last -1 r))  ;;=> "Elapsed time: 0.0615 msecs"

(def r-vec (vec r))      ;; to work like `butlast` pop needs a vector 
(time (pop r-vec))       ;;=> "Elapsed time: 0.062 msecs"
See Also

Returns the first item in the collection. Calls seq on its argument. If coll is nil, returns nil...

Added by boxie

Returns a possibly empty seq of the items after the first. Calls seq on its argument.

Added by boxie

Return the last item in coll, in linear time

Added by boxie

Returns a seq of the items after the first. Calls seq on its argument. If there are no more items...

Added by boxie

Return a lazy sequence of all but the last n (default 1) items in coll

Added by mmwaikar

Returns a seq of the last n items in coll. Depending on the type of coll may be no better than li...

Added by boxie

For a list or queue, returns a new list/queue without the first item, for a vector, returns a new ...

Added by miner
3 Notes
    By , created 9.6 years ago

    When using a vector, pop is faster than butlast.

    By , created 7.0 years ago

    pop will throw exception if the vector is empty, whereas butlast will return nil

    By , created 4.1 years ago, updated 4.1 years ago

    In my example, but-last is ~100 x slower than drop-last. butlast cannot remove multiple elements from the end, but drop-last can. butlast seems eager, and drop-last seems lazy. 'butlast' will return nil when empty, and drop-last will return '() when empty.