This page is a practical tutorial of Emacs Lisp's list and vector datatype. If you don't know elisp, first take a look at Emacs Lisp Basics.
Lisp has vector and list datatypes. These are similar to other language's {list, vector, array}.
To create a vector, write it like this (vector a b …).
If you do not want the elements evaluated, write it like this: [a b …].
;; creating a vector (setq v (vector 3 4 5)) ; each element will be evaluated (setq v [3 4 5]) ; each element will NOT be evaluated
(length (vector 3 4 5))
use elt.
(elt (vector 3 4 5) 0) ; ⇒ 3. index starts at 0
use aset.
(setq v [3 4 5]) (aset v 0 "b") v ; ⇒ ["b" 4 5]
;; nested vector [[1 2] [3 4]] ; 2 by 2 matrix [8 [3 [2 9] c] 7 [4 "b"]] ; random nested vector
One simple way to go thru a vector is using mapcar. Note that it returns a list, not vector.
;; add 1 to each (mapcar '1+ [3 4 5] ) ; ⇒ (4 5 6) ;; get first element of each row (mapcar (lambda (x) (elt x 0)) [[1 2] [3 4]] ) ; ⇒ (1 3)
If you want to map to list but don't need the return value, use mapc.
You can also use while. Example:
(setq v [3 4 5]) (setq i 0) (while (< i (length v)) (insert (format "%d" (elt v i))) (setq i (1+ i)) ) ; inserts "345"
You can join 2 vectors into a new vector by vconcat. You can convert a vector to list by append, ⁖ (append ‹myVector› nil).
(info "(elisp) Vector Functions")
To create a list, write it like this (list a b …).
If you do not want the elements evaluated, write it like this: '(a b …).
; prints a list (message "%S" '(a b c)) ; assign a list to a var (setq myList '(a b c)) ; create a list of values of variables (let ((x 3) (y 4) (z 5)) (message "%S" (list x y z)) ) ; prints "(3 4 5)"
| Function | Purpose |
|---|---|
| (car myList) | first element |
| (nth n myList) | nth element (start from 0) |
| (car (last myList)) | last element |
| (cdr myList) | 2nd to last elements |
| (nthcdr n myList) | nth to last elements |
| (butlast myList n) | without the last n elements |
Here's some example of lists and element extraction.
(car (list "a" "b" "c") ) ; ⇒ "a" (nth 1 (list "a" "b" "c") ) ; ⇒ "b" (car (last (list "a" "b" "c")) ) ; ⇒ "c" (cdr (list "a" "b" "c") ) ; ⇒ ("b" "c")
| Function | Purpose |
|---|---|
| (length myList) | number of elements |
| (cons x myList) | add x to front |
| (append myList1 myList2) | join two lists |
Examples:
(length (list "a" "b" "c") ) ; ⇒ 3 (cons "a" (list "c" "d") ) ; ⇒ ("a" "c" "d") (cons (list "a" "b") (list "c" "d") ) ; ⇒ (("a" "b") "c" "d") (append (list "a" "b") (list "c" "d") ) ; ⇒ ("a" "b" "c" "d")
| Function | Purpose |
|---|---|
| (pop myList) | Remove first element from the variable. Returns the removed element. |
| (nbutlast myList n) | Remove last n elements from the variable. Returns the new value of the variable. |
| (setcar myList x) | replaces the first element in myList with x. Returns x. |
| (setcdr myList x) | replaces the rest of elements in myList with x. Returns x. |
The weird names {car, cdr, cons} are like that for historical reasons.
Here's a typical way of going thru a list. It is done with mapcar or mapc. Use mapc when you don't need the return value.
; add one to each list member (mapcar (lambda (x) (+ x 1)) (list 1 2 3 4) ) ; ⇒ (2 3 4 5) ; add one to each list member using the build in function 1+ (mapcar '1+ (list 1 2 3 4)) ; ⇒ (2 3 4 5) ; take the 1st element of each element in the list (mapcar 'car '((1 2) (3 4) (5 6))) ; ⇒ (1 3 5) ; take the 2nd element of each element in the ilst (mapcar (lambda (x) (nth 1 x)) '((1 2) (3 4) (5 6))) ; ⇒ (2 4 6) ; apply a file processing function to a list of files (mapc 'my-update-html-footer (list "~/web/3d/viz.html" "~/web/3d/viz2.html" "~/web/dinju/Khajuraho.html" "~/web/dinju/Khajuraho2.html" "~/web/dinju/Khajuraho3.html" ) )
The lambda above pretty much means “subroutine”. It essentially let you define a function in the middle of your code. The form is (lambda (‹args›) ‹body›). For example, (lambda (x y) (+ x y)) would be a function that takes two arguments, x and y, and returns their sum.
Another common form to loop thru a list is using the while function. In each iteration, pop is used to reduce the list.
Here's a example of going thru a list using the while function.
(let (myList) (setq myList '(a b c)) (while myList (message "%s" (pop myList)) (sleep-for 1) ) )
Following is another example of using while to loop thru a list.
; pop head of myList ; prepend it to myList2 ; resulting a reversed list (let (myList myList2) (setq myList '(a b c)) (setq myList2 '()) (while myList (setq myList2 (cons (pop myList) myList2) ) ) myList2 )
First, use let to set a code block, with temporary variables “myList” and “myList2”. “myList” is then set to '(a b c). “myList2” is set to a empty list. Then, in the body of while, the (pop myList) drops myList's first element and returns it, the (cons (pop myList) myList2) creates a list with the new element prepended to “myList2”. (Note: This code is to illustrate going thru a list. If you want to reverse a list, use the reverse function.)
Lisp's list and vector both are subtypes of the “sequences” datatype. Many functions, such as {elt, mapcar}, work on any sequence type. Here's their primary differences:
cons, and can have the first element dropped by cdr. These operations has constant time.Lisp culture is to almost always use list. I recommend using vector as much as possible. Use list ONLY IF you need to constantly grow the list. Even for that case, i recommend using vector by starting with large length, using the function make-vector.
〔☛ Guy Steele on Parallel Programing: Get rid of cons!〕
You can nest list and vectors in any way. Example:
;; mixed nested list/vector [ '(3 4) '(5 8) [4 2]] (list [8 7] '(4 1))
(info "(elisp) Sequences Arrays Vectors")
Another important datatype similar to list and vector is called Association List (aka alist). It is similar to Python's dictionary or Perl's hash table or PHP's array. See: (info "(elisp) Association Lists").
For a example of using alist, see: Emacs Lisp: Batch Script to Validate Matching Brackets.
Elisp also has a true hash table, if you need large number of pairs. See: Emacs Lisp Hash Table.