PSC Code Manual

util/list.lsp [src]

List-handling functions

Functions

Function signature Description
(2-item-list lst) Returns the elements of LST grouped by twos
(3-item-list lst) Returns the elements of LST grouped by threes
(add-to-alist alist-sym key value append-p) Adds an entry for KEY to ALIST pointed to by ALIST-SYM
(add-to-list list-sym elt) Adds ELT to list referred to by LIST-SYM
(add-to-list-at-pos lst-sym elt pos) Adds ELT to list referred to by LST-SYM at POS
(append! lst-sym app-lst) Updates LST-SYM in place using append
(circular-nth n lst) Wrapper for nth that treats LST as periodic and infinite
(circular-shift lst n) Returns LST left-shifted N times
(cons-ind-lst len i) Returns a range of integers starting at I (optional) of length LEN, by 1
(count-items ci-lst) Returns a list of counts of items in CI-LST
(filter lst f) Returns LST without elements for which F returns nil
(filter! lst-sym f) Updates list at LST-STM in place using filter
(find-first pred lst) Returns the first element in LST for which PRED returns non-nil
(first-two lst) Returns the first two elements of LST
(list-of-strings-p x) Returns T if X is a list of strings
(lst* lstelt n) Returns a list consisting of ELE repeated N times
(map-append f lst) Alias for (apply 'append (mapcar f lst))
(mapcar! f lst-sym) Updates list at LST-SYM in place using mapcar
(member* target list2) Returns T if any members of TARGET appear in LST
(pop! pop-lst-sym) Sets LST-SYM to (cdr LST) and returns (car LST)
(range from to by) Returns a list of numbers that range from FROM to TO by step BY
(rcons lst x) Returns LST with X added to the end
(remove lst f) Returns LST with only elements for which F returns nil
(remove! lst-sym f) Updates list at LST-STM in place using remove
(remove-last lst) Returns LST without its last element
(remove-nth n lst) Returns LST with Nth item removed
(rpt-lst n ele) Returns a list consisting of ELE repeated N times
(safe-nth n lst) Wrapper for nth that returns nil when LST is nil
(slice lst start len) Return a slice from LST of length LEN starting at START
(sort! lst-sym f) Sorts LST in place using vl-sort
(split-list lst f true-lst-sym false-lst-sym) Puts items for which F returns nil in FALSE-LST and the rest in TRUE-LST
(split-list-n lst n first-lst-sym second-lst-sym) Splits LST on index N, putting first half in FIRST-LST and the rest in SECOND-LST
(strip-nil lst) Returns LST with nil elements removed
(subst! new old lst-sym) Updates list at LST-SYM in place using subst
(take n lst) Returns the first N elements of LST
(take! n take-lst-sym) Returns the first N elements from TAKE-LST-SYM, removing them
(take-while predicate lst) Returns the first elements of LST for which PREDICATE is true
(test-for test-type lst) Returns T if all elements of LST are of type TEST-TYPE
(uniquify lst) Returns LST without duplicate items
(zip l1 l2) Returns lists L1 and L2 interleaved

(2-item-list lst)

Returns the elements of LST grouped by twos

VARS:
(LST nil (LISTP LST))

TESTS:
(EQUAL (2-ITEM-LIST '(1 2 A B)) '((1 2) (A B)))
(EQUAL (2-ITEM-LIST '(1 2 A)) '((1 2) (A nil)))

(3-item-list lst)

Returns the elements of LST grouped by threes

VARS:
(LST nil (LISTP LST))

TESTS:
(EQUAL (3-ITEM-LIST '(1 2 3 A B C)) '((1 2 3) (A B C)))
(EQUAL (3-ITEM-LIST '(1 2 3 A B)) '((1 2 3) (A B nil)))

(add-to-alist alist-sym key value append-p)

Adds an entry for KEY to ALIST pointed to by ALIST-SYM

If ALIST already contains an entry for KEY, replace it. If so, and the following
conditions are met, append to the value of the entry rather than replacing:

1. APPEND-P must be non-nil
2. Original entry value and new value types must match
3. Types must be STR or LIST

VARS:
(ALIST-SYM SYM (SYM-LST-P ALIST-SYM))

TESTS:
(EQUAL ((LAMBDA (/ LST) (ADD-TO-ALIST 'LST 'A 1 nil))) '((A . 1)))
(EQUAL ((LAMBDA (LST) (ADD-TO-ALIST 'LST 'A 1 nil)) '((A . 2))) '((A . 1)))
(EQUAL ((LAMBDA (LST) (ADD-TO-ALIST 'LST 'A ", world" T)) '((A . "hello"))) '((A . "hello, world")))

(add-to-list list-sym elt)

Adds ELT to list referred to by LIST-SYM

VARS:
(LIST-SYM SYM (SYM-LST-P LIST-SYM))

TESTS:
(EQUAL ((LAMBDA (/ LST) (ADD-TO-LIST 'LST 1))) '(1))
(EQUAL ((LAMBDA (LST) (ADD-TO-LIST 'LST 2)) '(1)) '(1 2))

(add-to-list-at-pos lst-sym elt pos)

Adds ELT to list referred to by LST-SYM at POS

VARS:
(LST-SYM SYM (SYM-LST-P LST-SYM))
(POS INT)

TESTS:
(EQUAL ((LAMBDA (LST) (ADD-TO-LIST-AT-POS 'LST nil 1)) '(1 2)) '(1 nil 2))

(append! lst-sym app-lst)

Updates LST-SYM in place using append

VARS:
(LST-SYM SYM (SYM-LST-P LST-SYM))
(APP-LST nil (LISTP APP-LST))

TESTS:
(EQUAL ((LAMBDA (LST) (APPEND! 'LST '(3)) LST) '(1 2)) '(1 2 3))

(circular-nth n lst)

Wrapper for nth that treats LST as periodic and infinite

If a negative is supplied for N, index from the end of LST. If N is greater than the
length of LST, wrap around to the beginning again as many times as necessary.

VARS:
(N INT)
(LST nil (LISTP LST))

TESTS:
(= (CIRCULAR-NTH 1 '(1 2 3)) 2)
(= (CIRCULAR-NTH -1 '(1 2 3)) 3)
(= (CIRCULAR-NTH 3 '(1 2 3)) 1)
(= (CIRCULAR-NTH 6 '(1 2 3)) 1)

(circular-shift lst n)

Returns LST left-shifted N times

VARS:
(LST nil (LISTP LST))
(N INT)

TESTS:
(EQUAL (CIRCULAR-SHIFT '(1 2 3) 1) '(2 3 1))
(EQUAL (CIRCULAR-SHIFT '(1 2 3) 2) '(3 1 2))

(cons-ind-lst len i)

Returns a range of integers starting at I (optional) of length LEN, by 1

VARS:
(LEN INT)
(I (INT nil))

TESTS:
(EQUAL (CONS-IND-LST 3 nil) '(0 1 2))
(EQUAL (CONS-IND-LST 3 5) '(5 6 7))

(count-items ci-lst)

Returns a list of counts of items in CI-LST

Each itme in the return list is a 2-item list whose car is the element and whose cadr is
the count of that element in CI-LST.

VARS:
(CI-LST nil (LISTP CI-LST))

TESTS:
(EQUAL (COUNT-ITEMS '(1)) '((1 1)))
(EQUAL (COUNT-ITEMS '(1 1 2 2 2)) '((1 2) (2 3)))

(filter lst f)

Returns LST without elements for which F returns nil

F should be a quoted list like '(= X 1), where X is the element in question. F will be
processed by macro-expand.

VARS:
(LST nil (LISTP LST))
(F nil (LISTP F))

TESTS:
(EQUAL (FILTER '(1 2 3) '(< X 2)) '(1))
(EQUAL (FILTER '(1 2 3) '(> X 0)) '(1 2 3))

(filter! lst-sym f)

Updates list at LST-STM in place using filter

VARS:
(LST-SYM SYM (SYM-LST-P LST-SYM))
(F nil (LISTP F))

(find-first pred lst)

Returns the first element in LST for which PRED returns non-nil

PRED should be a function of one argument.

VARS:
(PRED nil (FUNCTION-OR-LAMBDA-P PRED))
(LST nil (LISTP LST))

TESTS:
(= (FIND-FIRST '(LAMBDA (A) (> A 1)) '(1 2 3)) 2)

(first-two lst)

Returns the first two elements of LST

VARS:
(LST nil (LISTP LST))

TESTS:
(EQUAL (FIRST-TWO '(1 2 3)) '(1 2))

(list-of-strings-p x)

Returns T if X is a list of strings

(lst* lstelt n)

Returns a list consisting of ELE repeated N times

Duplicate (args reversed) of rpt-lst.

VARS:
(N INT)

TESTS:
(EQUAL (LST* 'Q 3) '(Q Q Q))

(map-append f lst)

Alias for (apply 'append (mapcar f lst))

VARS:
(F nil (FUNCTION-OR-LAMBDA-P F))
(LST nil (LISTP LST))

TESTS:
(EQUAL (MAP-APPEND 'REVERSE '((1 2) (3 4))) '(2 1 4 3))

(mapcar! f lst-sym)

Updates list at LST-SYM in place using mapcar

VARS:
(F nil (FUNCTION-OR-LAMBDA-P F))
(LST-SYM SYM (SYM-LST-P LST-SYM))

TESTS:
(EQUAL ((LAMBDA (LST) (MAPCAR! '1+ 'LST) LST) '(1 2 3)) '(2 3 4))

(member* target list2)

Returns T if any members of TARGET appear in LST

TARGET can be a list or atom.

VARS:
(LIST2 nil (LISTP LIST2))

TESTS:
(MEMBER 'A '(A B))
(NOT (MEMBER 'C '(A B)))
(MEMBER* '(A 1) '(A B))
(MEMBER* '(A 1) '(1 2))
(NOT (MEMBER* '(A B) '(1 2)))

(pop! pop-lst-sym)

Sets LST-SYM to (cdr LST) and returns (car LST)

VARS:
(POP-LST-SYM SYM)

TESTS:
(EQUAL ((LAMBDA (LST) (POP! 'LST)) nil) nil)
(EQUAL ((LAMBDA (LST) (POP! 'LST)) '(1)) 1)
(EQUAL ((LAMBDA (LST) (POP! 'LST) LST) '(1 2)) '(2))

(range from to by)

Returns a list of numbers that range from FROM to TO by step BY

TO is exclusive

VARS:
(FROM nil (NUMBERP FROM))
(TO nil (NUMBERP TO))
(BY nil (NUMBERP BY))

TESTS:
(EQUAL (RANGE 1 4 1) '(1 2 3))
(EQUAL (RANGE 0.75 1.25 0.125) '(0.75 0.875 1.0 1.125))

(rcons lst x)

Returns LST with X added to the end

VARS:
(LST nil (LISTP LST))

TESTS:
(EQUAL (RCONS '(1) 2) '(1 2))
(EQUAL (RCONS nil 1) '(1))

(remove lst f)

Returns LST with only elements for which F returns nil

F should be a quoted list like '(= X 1), where X is the element in question. F will be
processed by macro-expand.

VARS:
(LST nil (LISTP LST))
(F nil (LISTP F))

TESTS:
(EQUAL (REMOVE '(1 2 3) '(> X 1)) '(1))
(EQUAL (REMOVE '(1 2 3) '(< X 1)) '(1 2 3))

(remove! lst-sym f)

Updates list at LST-STM in place using remove

VARS:
(LST-SYM SYM (SYM-LST-P LST-SYM))
(F nil (LISTP F))

TESTS:
(EQUAL ((LAMBDA (LST) (REMOVE! 'LST '(> X 1)) LST) '(1 2 3)) '(1))
(EQUAL ((LAMBDA (LST) (REMOVE! 'LST '(< X 1)) LST) '(1 2 3)) '(1 2 3))

(remove-last lst)

Returns LST without its last element

VARS:
(LST nil (LISTP LST))

TESTS:
(EQUAL (REMOVE-LAST '(1 2 3)) '(1 2))

(remove-nth n lst)

Returns LST with Nth item removed

VARS:
(N INT)
(LST nil (LISTP LST))

TESTS:
(EQUAL (REMOVE-NTH 1 '(1 2 3)) '(1 3))

(rpt-lst n ele)

Returns a list consisting of ELE repeated N times

Duplicate (args reversed) of lst**.

VARS:
(N INT)

TESTS:
(EQUAL (RPT-LST 3 'Q) '(Q Q Q))

(safe-nth n lst)

Wrapper for nth that returns nil when LST is nil

Built-in nth errors in that case.

VARS:
(N INT)
(LST nil (LISTP LST))

TESTS:
(= (SAFE-NTH 1 '(1 2)) 2)
(= (SAFE-NTH 1 nil) nil)

(slice lst start len)

Return a slice from LST of length LEN starting at START

VARS:
(LST nil (LISTP LST))
(START INT)
(LEN INT)

TESTS:
(EQUAL (SLICE '(1 2 3 4) 0 4) '(1 2 3 4))
(EQUAL (SLICE '(1 2 3 4) 1 2) '(2 3))

(sort! lst-sym f)

Sorts LST in place using vl-sort

VARS:
(LST-SYM SYM (SYM-LST-P LST-SYM))
(F nil (FUNCTION-OR-LAMBDA-P F))

TESTS:
(EQUAL ((LAMBDA (LST) (SORT! 'LST '<) LST) '(2 1 3)) '(1 2 3))

(split-list lst f true-lst-sym false-lst-sym)

Puts items for which F returns nil in FALSE-LST and the rest in TRUE-LST

See remove and filter for how to format F.

VARS:
(LST nil (LISTP LST))
(TRUE-LST-SYM SYM (SYM-LST-P TRUE-LST-SYM))
(FALSE-LST-SYM SYM (SYM-LST-P FALSE-LST-SYM))

(split-list-n lst n first-lst-sym second-lst-sym)

Splits LST on index N, putting first half in FIRST-LST and the rest in SECOND-LST

VARS:
(LST nil (LISTP LST))
(N INT)
(FIRST-LST-SYM SYM (SYM-LST-P FIRST-LST-SYM))
(SECOND-LST-SYM SYM (SYM-LST-P SECOND-LST-SYM))

(strip-nil lst)

Returns LST with nil elements removed

VARS:
(LST nil (LISTP LST))

TESTS:
(EQUAL (STRIP-NIL '(1 nil 2)) '(1 2))
(EQUAL (STRIP-NIL '(1 2 3)) '(1 2 3))

(subst! new old lst-sym)

Updates list at LST-SYM in place using subst

VARS:
(LST-SYM SYM (SYM-LST-P LST-SYM))

TESTS:
(EQUAL ((LAMBDA (LST) (SUBST! 'A 1 'LST) LST) '(1)) '(A))
(EQUAL ((LAMBDA (LST) (SUBST! 'A 1 'LST) LST) '(2)) '(2))

(take n lst)

Returns the first N elements of LST

VARS:
(N INT)
(LST nil (LISTP LST))

TESTS:
(EQUAL (TAKE 1 '(1 2)) '(1))
(EQUAL (TAKE 2 '(1)) '(1))
(= (TAKE 1 nil) nil)

(take! n take-lst-sym)

Returns the first N elements from TAKE-LST-SYM, removing them

VARS:
(N (INT))
(TAKE-LST-SYM SYM (LISTP (VL-SYMBOL-VALUE TAKE-LST-SYM)))

TESTS:
(EQUAL ((LAMBDA (LST) (TAKE! 1 'LST)) '(1 2)) '(1))
(EQUAL ((LAMBDA (LST) (TAKE! 1 'LST) LST) '(1 2)) '(2))

(take-while predicate lst)

Returns the first elements of LST for which PREDICATE is true

PREDICATE should be a function that takes one element.

VARS:
(PREDICATE (LIST SYM) (IF (LISTP PREDICATE) (= (CAR PREDICATE) 'LAMBDA) (FUNCTION-P (VL-SYMBOL-VALUE PREDICATE))))
(LST (LIST nil) (LISTP LST))

TESTS:
(EQUAL (TAKE-WHILE 'NUMBERP '(1 2 nil 3)) '(1 2))

(test-for test-type lst)

Returns T if all elements of LST are of type TEST-TYPE

VARS:
(TEST-TYPE SYM)
(LST nil (LISTP LST))

TESTS:
(TEST-FOR 'INT '(1 2 3))
(TEST-FOR 'SYM '(A B C))
(NOT (TEST-FOR 'INT '(1 2 3.0)))

(uniquify lst)

Returns LST without duplicate items

VARS:
(LST nil (LISTP LST))

TESTS:
'(EQUAL (UNIQUIFY '(1 2 3 1 2)) '(1 2 3))

(zip l1 l2)

Returns lists L1 and L2 interleaved

VARS:
(L1 LIST (>= (LENGTH L1) (LENGTH L2)))
(L2 (LIST nil))

TESTS:
(EQUAL (ZIP '(1 2) '(A B)) '(1 A 2 B))
(EQUAL (ZIP '(1 2 3) '(A)) '(1 A 2 3))