Skip to content

Other list operations

Other list functions not fit to be classified elsewhere.

Function: -rotate (n list)

Rotate list n places to the right (left if n is negative). The time complexity is o(n).

emacs-lisp
(-rotate 3 '(1 2 3 4 5 6 7))
    ⇒ (5 6 7 1 2 3 4)
emacs-lisp
(-rotate -3 '(1 2 3 4 5 6 7))
    ⇒ (4 5 6 7 1 2 3)
emacs-lisp
(-rotate 16 '(1 2 3 4 5 6 7))
    ⇒ (6 7 1 2 3 4 5)

Function: -cons* (&rest args)

Make a new list from the elements of args. The last 2 elements of args are used as the final cons of the result, so if the final element of args is not a list, the result is a dotted list. With no args, return nil.

emacs-lisp
(-cons* 1 2)
    ⇒ (1 . 2)
emacs-lisp
(-cons* 1 2 3)
    ⇒ (1 2 . 3)
emacs-lisp
(-cons* 1)
1

Function: -snoc (list elem &rest elements)

Append elem to the end of the list.

This is like cons, but operates on the end of list.

If any elements are given, append them to the list as well.

emacs-lisp
(-snoc '(1 2 3) 4)
    ⇒ (1 2 3 4)
emacs-lisp
(-snoc '(1 2 3) 4 5 6)
    ⇒ (1 2 3 4 5 6)
emacs-lisp
(-snoc '(1 2 3) '(4 5 6))
    ⇒ (1 2 3 (4 5 6))

Function: -interpose (sep list)

Return a new list of all elements in list separated by sep.

emacs-lisp
(-interpose "-" ())
    ⇒ ()
emacs-lisp
(-interpose "-" '("a"))
    ⇒ ("a")
emacs-lisp
(-interpose "-" '("a" "b" "c"))
    ⇒ ("a" "-" "b" "-" "c")

Function: -interleave (&rest lists)

Return a new list of the first item in each list, then the second etc.

emacs-lisp
(-interleave '(1 2) '("a" "b"))
    ⇒ (1 "a" 2 "b")
emacs-lisp
(-interleave '(1 2) '("a" "b") '("A" "B"))
    ⇒ (1 "a" "A" 2 "b" "B")
emacs-lisp
(-interleave '(1 2 3) '("a" "b"))
    ⇒ (1 "a" 2 "b")

Function: -iota (count &optional start step)

Return a list containing count numbers. Starts from start and adds step each time. The default start is zero, the default step is 1. This function takes its name from the corresponding primitive in the apl language.

emacs-lisp
(-iota 6)
    ⇒ (0 1 2 3 4 5)
emacs-lisp
(-iota 4 2.5 -2)
    ⇒ (2.5 0.5 -1.5 -3.5)
emacs-lisp
(-iota -1)
    error→ Wrong type argument: natnump, -1

Function: -zip-with (fn list1 list2)

Zip list1 and list2 into a new list using the function fn. That is, apply fn pairwise taking as first argument the next element of list1 and as second argument the next element of list2 at the corresponding position. The result is as long as the shorter list.

This function’s anaphoric counterpart is --zip-with.

For other zips, see also -zip-lists (see -zip-lists) and -zip-fill (see -zip-fill).

emacs-lisp
(-zip-with #'+ '(1 2 3 4) '(5 6 7))
    ⇒ (6 8 10)
emacs-lisp
(-zip-with #'cons '(1 2 3) '(4 5 6 7))
    ⇒ ((1 . 4) (2 . 5) (3 . 6))
emacs-lisp
(--zip-with (format "%s & %s" it other) '(Batman Jekyll) '(Robin Hyde))
    ⇒ ("Batman & Robin" "Jekyll & Hyde")

Function: -zip-pair (list1 list2)

Zip list1 and list2 together.

Make a pair with the head of each list, followed by a pair with the second element of each list, and so on. The number of pairs returned is equal to the length of the shorter input list.

See also: -zip-lists (see -zip-lists).

emacs-lisp
(-zip-pair '(1 2 3 4) '(5 6 7))
    ⇒ ((1 . 5) (2 . 6) (3 . 7))
emacs-lisp
(-zip-pair '(1 2 3) '(4 5 6))
    ⇒ ((1 . 4) (2 . 5) (3 . 6))
emacs-lisp
(-zip-pair '(1 2) '(3))
    ⇒ ((1 . 3))

Function: -zip-lists (&rest lists)

Zip lists together.

Group the head of each list, followed by the second element of each list, and so on. The number of returned groupings is equal to the length of the shortest input list, and the length of each grouping is equal to the number of input lists.

The return value is always a list of proper lists, in contrast to -zip (see -zip) which returns a list of dotted pairs when only two input lists are provided.

See also: -zip-pair (see -zip-pair).

emacs-lisp
(-zip-lists '(1 2 3) '(4 5 6))
    ⇒ ((1 4) (2 5) (3 6))
emacs-lisp
(-zip-lists '(1 2 3) '(4 5 6 7))
    ⇒ ((1 4) (2 5) (3 6))
emacs-lisp
(-zip-lists '(1 2) '(3 4 5) '(6))
    ⇒ ((1 3 6))

Function: -zip-lists-fill (fill-value &rest lists)

Zip lists together, padding shorter lists with fill-value. This is like -zip-lists (see -zip-lists) (which see), except it retains all elements at positions beyond the end of the shortest list. The number of returned groupings is equal to the length of the longest input list, and the length of each grouping is equal to the number of input lists.

emacs-lisp
(-zip-lists-fill 0 '(1 2) '(3 4 5) '(6))
    ⇒ ((1 3 6) (2 4 0) (0 5 0))
emacs-lisp
(-zip-lists-fill 0 '(1 2) '(3 4) '(5 6))
    ⇒ ((1 3 5) (2 4 6))
emacs-lisp
(-zip-lists-fill 0 '(1 2 3) nil)
    ⇒ ((1 0) (2 0) (3 0))

Function: -zip (&rest lists)

Zip lists together.

Group the head of each list, followed by the second element of each list, and so on. The number of returned groupings is equal to the length of the shortest input list, and the number of items in each grouping is equal to the number of input lists.

If only two lists are provided as arguments, return the groupings as a list of dotted pairs. Otherwise, return the groupings as a list of proper lists.

Since the return value changes form depending on the number of arguments, it is generally recommended to use -zip-lists (see -zip-lists) instead, or -zip-pair (see -zip-pair) if a list of dotted pairs is desired.

See also: -unzip (see -unzip).

emacs-lisp
(-zip '(1 2 3 4) '(5 6 7) '(8 9))
    ⇒ ((1 5 8) (2 6 9))
emacs-lisp
(-zip '(1 2 3) '(4 5 6) '(7 8 9))
    ⇒ ((1 4 7) (2 5 8) (3 6 9))
emacs-lisp
(-zip '(1 2 3))
    ⇒ ((1) (2) (3))

Function: -zip-fill (fill-value &rest lists)

Zip lists together, padding shorter lists with fill-value. This is like -zip (see -zip) (which see), except it retains all elements at positions beyond the end of the shortest list. The number of returned groupings is equal to the length of the longest input list, and the length of each grouping is equal to the number of input lists.

Since the return value changes form depending on the number of arguments, it is generally recommended to use -zip-lists-fill (see -zip-lists-fill) instead, unless a list of dotted pairs is explicitly desired.

emacs-lisp
(-zip-fill 0 '(1 2 3) '(4 5))
    ⇒ ((1 . 4) (2 . 5) (3 . 0))
emacs-lisp
(-zip-fill 0 () '(1 2 3))
    ⇒ ((0 . 1) (0 . 2) (0 . 3))
emacs-lisp
(-zip-fill 0 '(1 2) '(3 4) '(5 6))
    ⇒ ((1 3 5) (2 4 6))

Function: -unzip-lists (lists)

Unzip lists.

This works just like -zip-lists (see -zip-lists) (which see), but takes a list of lists instead of a variable number of arguments, such that

(-unzip-lists (-zip-lists args…))

is identity (given that the lists comprising args are of the same length).

emacs-lisp
(-unzip-lists (-zip-lists '(1 2) '(3 4) '(5 6)))
    ⇒ ((1 2) (3 4) (5 6))
emacs-lisp
(-unzip-lists '((1 2 3) (4 5) (6 7) (8 9)))
    ⇒ ((1 4 6 8) (2 5 7 9))
emacs-lisp
(-unzip-lists '((1 2 3) (4 5 6)))
    ⇒ ((1 4) (2 5) (3 6))

Function: -unzip (lists)

Unzip lists.

This works just like -zip (see -zip) (which see), but takes a list of lists instead of a variable number of arguments, such that

(-unzip (-zip l1 l2 l3 …))

is identity (given that the lists are of the same length, and that -zip (see -zip) is not called with two arguments, because of the caveat described in its docstring).

Note in particular that calling -unzip (see -unzip) on a list of two lists will return a list of dotted pairs.

Since the return value changes form depending on the number of lists, it is generally recommended to use -unzip-lists (see -unzip-lists) instead.

emacs-lisp
(-unzip (-zip '(1 2) '(3 4) '(5 6)))
    ⇒ ((1 . 2) (3 . 4) (5 . 6))
emacs-lisp
(-unzip '((1 2 3) (4 5 6)))
    ⇒ ((1 . 4) (2 . 5) (3 . 6))
emacs-lisp
(-unzip '((1 2 3) (4 5) (6 7) (8 9)))
    ⇒ ((1 4 6 8) (2 5 7 9))

Function: -pad (fill-value &rest lists)

Pad each of lists with fill-value until they all have equal lengths.

Ensure all lists are as long as the longest one by repeatedly appending fill-value to the shorter lists, and return the resulting lists.

emacs-lisp
(-pad 0 ())
    ⇒ (nil)
emacs-lisp
(-pad 0 '(1 2) '(3 4))
    ⇒ ((1 2) (3 4))
emacs-lisp
(-pad 0 '(1 2) '(3 4 5 6) '(7 8 9))
    ⇒ ((1 2 0 0) (3 4 5 6) (7 8 9 0))

Function: -table (fn &rest lists)

Compute outer product of lists using function fn.

The function fn should have the same arity as the number of supplied lists.

The outer product is computed by applying fn to all possible combinations created by taking one element from each list in order. The dimension of the result is (length lists).

See also: -table-flat (see -table-flat)

emacs-lisp
(-table '* '(1 2 3) '(1 2 3))
    ⇒ ((1 2 3) (2 4 6) (3 6 9))
emacs-lisp
(-table (lambda (a b) (-sum (-zip-with '* a b))) '((1 2) (3 4)) '((1 3) (2 4)))
    ⇒ ((7 15) (10 22))
emacs-lisp
(apply '-table 'list (-repeat 3 '(1 2)))
    ⇒ ((((1 1 1) (2 1 1)) ((1 2 1) (2 2 1))) (((1 1 2) (2 1 2)) ((1 2 2) (2 2 2))))

Function: -table-flat (fn &rest lists)

Compute flat outer product of lists using function fn.

The function fn should have the same arity as the number of supplied lists.

The outer product is computed by applying fn to all possible combinations created by taking one element from each list in order. The results are flattened, ignoring the tensor structure of the result. This is equivalent to calling:

(-flatten-n (1- (length lists)) (apply ’-table fn lists))

but the implementation here is much more efficient.

See also: -flatten-n (see -flatten-n), -table (see -table)

emacs-lisp
(-table-flat 'list '(1 2 3) '(a b c))
    ⇒ ((1 a) (2 a) (3 a) (1 b) (2 b) (3 b) (1 c) (2 c) (3 c))
emacs-lisp
(-table-flat '* '(1 2 3) '(1 2 3))
    ⇒ (1 2 3 2 4 6 3 6 9)
emacs-lisp
(apply '-table-flat 'list (-repeat 3 '(1 2)))
    ⇒ ((1 1 1) (2 1 1) (1 2 1) (2 2 1) (1 1 2) (2 1 2) (1 2 2) (2 2 2))

Function: -first (pred list)

Return the first item in list for which pred returns non-nil. Return nil if no such element is found.

To get the first item in the list no questions asked, use -first-item (see -first-item).

Alias: -find.

This function’s anaphoric counterpart is --first.

emacs-lisp
(-first #'natnump '(-1 0 1))
0
emacs-lisp
(-first #'null '(1 2 3))
nil
emacs-lisp
(--first (> it 2) '(1 2 3))
3

Function: -last (pred list)

Return the last x in list where (pred x) is non-nil, else nil.

emacs-lisp
(-last 'even? '(1 2 3 4 5 6 3 3 3))
6
emacs-lisp
(-last 'even? '(1 3 7 5 9))
nil
emacs-lisp
(--last (> (length it) 3) '("a" "looong" "word" "and" "short" "one"))
"short"

Function: -first-item (list)

Return the first item of list, or nil on an empty list.

See also: -second-item (see -second-item), -last-item (see -last-item), etc.

emacs-lisp
(-first-item ())
    ⇒ ()
emacs-lisp
(-first-item '(1 2 3 4 5))
1
emacs-lisp
(let ((list (list 1 2 3))) (setf (-first-item list) 5) list)
    ⇒ (5 2 3)

Function: -second-item (list)

Return the second item of list, or nil if list is too short.

See also: -first-item (see -first-item), -third-item (see -third-item), etc.

emacs-lisp
(-second-item ())
    ⇒ ()
emacs-lisp
(-second-item '(1 2 3 4 5))
2
emacs-lisp
(let ((list (list 1 2))) (setf (-second-item list) 5) list)
    ⇒ (1 5)

Function: -third-item (list)

Return the third item of list, or nil if list is too short.

See also: -second-item (see -second-item), -fourth-item (see -fourth-item), etc.

emacs-lisp
(-third-item ())
    ⇒ ()
emacs-lisp
(-third-item '(1 2))
    ⇒ ()
emacs-lisp
(-third-item '(1 2 3 4 5))
3

Function: -fourth-item (list)

Return the fourth item of list, or nil if list is too short.

See also: -third-item (see -third-item), -fifth-item (see -fifth-item), etc.

emacs-lisp
(-fourth-item ())
    ⇒ ()
emacs-lisp
(-fourth-item '(1 2 3))
    ⇒ ()
emacs-lisp
(-fourth-item '(1 2 3 4 5))
4

Function: -fifth-item (list)

Return the fifth item of list, or nil if list is too short.

See also: -fourth-item (see -fourth-item), -last-item (see -last-item), etc.

emacs-lisp
(-fifth-item ())
    ⇒ ()
emacs-lisp
(-fifth-item '(1 2 3 4))
    ⇒ ()
emacs-lisp
(-fifth-item '(1 2 3 4 5))
5

Function: -last-item (list)

Return the last item of list, or nil on an empty list.

See also: -first-item (see -first-item), etc.

emacs-lisp
(-last-item ())
    ⇒ ()
emacs-lisp
(-last-item '(1 2 3 4 5))
5
emacs-lisp
(let ((list (list 1 2 3))) (setf (-last-item list) 5) list)
    ⇒ (1 2 5)

Function: -butlast (list)

Return a list of all items in list except for the last.

emacs-lisp
(-butlast '(1 2 3))
    ⇒ (1 2)
emacs-lisp
(-butlast '(1 2))
    ⇒ (1)
emacs-lisp
(-butlast '(1))
nil

Function: -sort (comparator list)

Sort list, stably, comparing elements using comparator. Return the sorted list. list is not modified by side effects. comparator is called with two elements of list, and should return non-nil if the first element should sort before the second.

emacs-lisp
(-sort #'< '(3 1 2))
    ⇒ (1 2 3)
emacs-lisp
(-sort #'> '(3 1 2))
    ⇒ (3 2 1)
emacs-lisp
(--sort (< it other) '(3 1 2))
    ⇒ (1 2 3)

Function: -list (arg)

Ensure arg is a list. If arg is already a list, return it as is (not a copy). Otherwise, return a new list with arg as its only element.

Another supported calling convention is (-list &rest args). In this case, if arg is not a list, a new list with all of args as elements is returned. This use is supported for backward compatibility and is otherwise deprecated.

emacs-lisp
(-list 1)
    ⇒ (1)
emacs-lisp
(-list ())
    ⇒ ()
emacs-lisp
(-list '(1 2 3))
    ⇒ (1 2 3)

Function: -fix (fn list)

Compute the (least) fixpoint of fn with initial input list.

fn is called at least once, results are compared with equal.

emacs-lisp
(-fix (lambda (l) (-non-nil (--mapcat (-split-at (/ (length it) 2) it) l))) '((1 2 3)))
    ⇒ ((1) (2) (3))
emacs-lisp
(let ((l '((starwars scifi) (jedi starwars warrior)))) (--fix (-uniq (--mapcat (cons it (cdr (assq it l))) it)) '(jedi book)))
    ⇒ (jedi starwars warrior scifi book)