Fresh from the oven:
=E3=80=88Emacs Lisp Tutorial: List =EF=BC=86 Vector=E3=80=89
http://xahlee.org/emacs/elisp_list_vector.html
(for beginner lisper only)
plain text version follows. heavy use of unicode. also has html
tables.
-------------------------------------------------
Emacs Lisp Tutorial: List =EF=BC=86 Vector
Xah Lee, 2011-02-21
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.
=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
=81=E2=94=81=E2=94=81=E2=94=81
Vectors
To create a vector, write it like this (vector a b =E2=80=A6).
If you do not want the elements evaluated, write it like this: [a b
=E2=80=A6].
Creating a vector:
;; 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:
(length (vector 3 4 5))
Getting a Element:
use =E2=80=9Celt=E2=80=9D.
(elt (vector 3 4 5) 0) ; =E2=87=92 3. index starts at 0
Changing a Element:
use =E2=80=9Caset=E2=80=9D.
(setq v [3 4 5])
(aset v 0 "b")
v ; =E2=87=92 ["b" 4 5]
=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80
Nested Vector
;; nested vector
[[1 2] [3 4]] ; 2 by 2 matrix
[8 [3 [2 9] c] 7 [4 "b"]] ; random nested vector
=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80
Looping Thru 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] ) ; =E2=87=92 (4 5 6)
;; get first element of each row
(mapcar (lambda (x) (elt x 0)) [[1 2] [3 4]] ) ; =E2=87=92 (1 3)
You can also use =E2=80=9Cwhile=E2=80=9D. Example:
(setq v [3 4 5])
(setq i 0)
(while (< i (length v))
(insert (format "%i" (elt v i)))
(setq i (1+ i)) ) ; inserts "345"
=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80
Join and Misc
You can join 2 vectors into a new vector by =E2=80=9Cvconcat=E2=80=9D. You =
can convert
a vector to list by =E2=80=9Cappend=E2=80=9D, e.g. (append myVector nil).
(info "(elisp) Vector Functions")
=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
=81=E2=94=81=E2=94=81=E2=94=81
List
To create a list, write it like this (list a b =E2=80=A6).
If you do not want the elements evaluated, write it like this: '(a b
=E2=80=A6).
; 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)"
Some List Element Extraction Functions 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") ) ; =E2=87=92 "a"
(nth 1 (list "a" "b" "c") ) ; =E2=87=92 "b"
(car (last (list "a" "b" "c")) ) ; =E2=87=92 "c"
(cdr (list "a" "b" "c") ) ; =E2=87=92 ("b" "c")
Basic List Functions 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") ) ; =E2=87=92 3
(cons "a" (list "c" "d") ) ; =E2=87=92 ("a" "c" "d")
(cons (list "a" "b") (list "c" "d") ) ; =E2=87=92 (("a" "b") "c" "d")
(append (list "a" "b") (list "c" "d") ) ; =E2=87=92 ("a" "b" "c" "d")
Functions that modify a list variable 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 =E2=80=9Ccar=E2=80=9D, =E2=80=9Ccdr=E2=80=9D, and =E2=80=9C=
cons=E2=80=9D are like that for historical
reasons.
(info "(elisp) Lists")
=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80
Looping Thru a List
Here's a typical way of going thru a list. It is done with =E2=80=9Cmapcar=
=E2=80=9D.
; add one to each list member
(mapcar (lambda (x) (+ x 1)) (list 1 2 3 4)) ; =E2=87=92 (2 3 4 5)
; add one to each list member using the build in function 1+
(mapcar '1+ (list 1 2 3 4)) ; =E2=87=92 (2 3 4 5)
; take the 1st element of each element in the list
(mapcar 'car '((1 2) (3 4) (5 6))) ; =E2=87=92 (1 3 5)
(mapcar 'car '((1 2) (3 4) (5 6))) ; =E2=87=92 (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))) ; =E2=87=92 (2 4 6)
; apply a file processing function to a list of files
(mapcar 'my-update-html-footer
(list
"/home/vicky/web/3d/viz.html"
"/home/vicky/web/3d/viz2.html"
"/home/vicky/web/dinju/Khajuraho.html"
"/home/vicky/web/dinju/Khajuraho2.html"
"/home/vicky/web/dinju/Khajuraho3.html"
)
)
The =E2=80=9Clambda=E2=80=9D above pretty much means =E2=80=9Csubroutine=E2=
=80=9D. It essentially let
you define a function in the middle of your code. The form is (lambda
arguments body). For example, (lambda (x y) (+ x y)) would be a
function that takes two arguments, x and y, and returns their sum.
Loop thru List with =E2=80=9Cwhile=E2=80=9D
Another common form to loop thru a list is using the =E2=80=9Cwhile=E2=80=
=9D function.
In each iteration, =E2=80=9Cpop=E2=80=9D is used to reduce the list. Here's=
a example
of going thru a list using the =E2=80=9Cwhile=E2=80=9D function.
(let (mylist)
(setq mylist '(a b c))
(while mylist
(message "%s" (pop mylist))
(sleep-for 1)
)
)
Following is another example of using =E2=80=9Cwhile=E2=80=9D 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 =E2=80=9Clet=E2=80=9D to set a code block, with temporary variab=
les
=E2=80=9Cmylist=E2=80=9D and =E2=80=9Cmylist2=E2=80=9D. =E2=80=9Cmylist=E2=
=80=9D is then set to '(a b c). =E2=80=9Cmylist2=E2=80=9D is
set to a empty list. Then, in the body of =E2=80=9Cwhile=E2=80=9D, 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 =E2=80=9Cmylist2=
=E2=80=9D.
(Note: This code is to illustrate going thru a list. If you want to
reverse a list, use the =E2=80=9Creverse=E2=80=9D function.)
=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=
=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=81=E2=94=
=81=E2=94=81=E2=94=81=E2=94=81
List vs Vector
Lisp's =E2=80=9Clist=E2=80=9D and =E2=80=9Cvector=E2=80=9D datatypes are al=
so called =E2=80=9Csequences=E2=80=9D. Many
functions, such as =E2=80=9Celt=E2=80=9D, =E2=80=9Cmapcar=E2=80=9D, work on=
any sequence type. Here's
their primary differences:
* vector has constant time access to any element.
* It takes proportionally longer time to access a long list.
* list's length can grow by pre-pending with =E2=80=9Ccons=E2=80=9D and=
is fast.
=E2=80=9Cvector=E2=80=9D's length cannot change.
You can nest list and vectors in any way. Example:
;; arbitrary nested list or vector
[ '(3 4) '(5 8) [4 2]]
(list [8 7] '(4 1))
(info "(elisp) Sequences Arrays Vectors")
Xah =E2=88=91 http://xahlee.org/
|