Return a seq of all but the last item in coll, in linear time
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"
Returns the first item in the collection. Calls seq on its argument. If coll is nil, returns nil...
Returns a possibly empty seq of the items after the first. Calls seq on its argument.
Returns a seq of the items after the first. Calls seq on its argument. If there are no more items...
Return a lazy sequence of all but the last n (default 1) items in coll
Returns a seq of the last n items in coll. Depending on the type of coll may be no better than li...
For a list or queue, returns a new list/queue without the first item, for a vector, returns a new ...
pop
will throw exception if the vector is empty, whereas butlast
will return nil
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.