Emacs Lisp: Map / Loop Thru List / Vector
Typical way to go thru a sequence is using
mapcar. Note that it returns a list, even if input is a vector.
〔►see Emacs Lisp: List vs Vector〕
(mapcar FUNCTION SEQUENCE) → Apply FUNCTION to each element of SEQUENCE, and make a list of the results. The result is a list, with same length as SEQUENCE. SEQUENCE may be a list, a vector, a bool-vector, or a string.
;; add 1 to each vector element (mapcar '1+ [3 4 5] ) ; (4 5 6)
;; add one to each list element (mapcar '1+ '(3 4 5)) ; (4 5 6)
1+ is a lisp function. It adds 1 to argument and returns it. For example,
(1+ 2) returns 3.
To use a function in
mapcar, you need to quote the function's name.
is a function, so we quote it and have
Here's another example.
; take the 1st element of each (mapcar 'car '((1 2) (3 4) (5 6))) ; (1 3 5)
list and vector are sequence
In emacs lisp, list and vector types are both considered sequences.
Many functions work with sequences. (that is, argument can be list or vector)
〔►see Emacs Lisp: List vs Vector〕
mapcar with lambda
mapcar is most commonly used with lambda. Here's a example:
;; get first element of each row (mapcar (lambda (x) (elt x 0)) [[1 2] [3 4]] ) ; ⇒ (1 3)
lambda means function, often known as “anonymous function”. It let you define a function in the middle of your code.
The form is
(lambda (args) body).
(lambda (x y) (+ x y)) is a function that takes two arguments, x and y, and returns their sum.
More examples with lambda:
; add one to each list member (mapcar (lambda (x) (+ x 1)) (list 1 2 3 4) ) ; (2 3 4 5)
;; take the 2nd element of each (mapcar (lambda (x) (nth 1 x)) '((1 2) (3 4) (5 6))) ; (2 4 6)
If you don't need map to return the sequence, use
mapc → like
mapcar, but returns nil.
;; apply a file processing function to a list of files (mapc 'my-update-html-footer (list "~/web/file1.html" "~/web/file2.html" "~/web/file3.html" ))
;; example of mapc on vector (mapc (lambda (x) (insert (number-to-string (aref x 0)))) [[1 2] [3 4]] ) ;; insert first element of each row into buffer ;; (it inserts 13) ;; returns nil
(dolist (VAR LIST) BODY) → Loop over a list. Evaluate BODY with VAR bound to each element from LIST, returns nil.
(dolist (VAR LIST RESULT) BODY) → returns RESULT.
(let ( (xlist (number-sequence 97 122)) ;; list 97 to 122 ) (dolist (n xlist) (insert n))) ;; inserts ;; abcdefghijklmnopqrstuvwxyz
The major difference between
dolist uses expression,
mapc uses a function.
dolist work with list only,
mapc works with list and vectors.
dotimes is useful when you want to go thru a list by a increasing index.
(dotimes (VAR COUNT) BODY …) → Loop a certain number of times. Evaluate BODY with VAR bound to successive integers running from 0, inclusive, to COUNT, exclusive. Returns nil
(dotimes (VAR COUNT RESULT) BODY …) → After loop, evaluate RESULT to get the return value.
(dotimes (i 4) (insert (number-to-string i))) ;; inserts "0123", returns nil
(let ((v [3 4 5])) (dotimes (i (length v)) (insert (number-to-string (elt v i))))) ; inserts 345
Another common form to loop thru a list is using the
while function. In each iteration,
pop is used to reduce the list.
(let ((mylist '(a b c))) (while mylist (message "%s" (pop mylist)) (sleep-for 1)))
Example with vector:
(setq v [3 4 5]) (setq i 0) (while (< i (length v)) (insert (format "%d" (elt v i))) (setq i (1+ i))) ; inserts "345"
Exit Loop/Function, catch/throw
or, buy something from Best Keyboard for Emacs