Search code examples
elisp

How to iterate over nested alist in emacs lisp?


I want to iterate over this my-list. How to do it?

(setq my-list '[((a . 1) (b . 2))  ((c . 3))])
(loop for k in my-list do
  (cl-loop for (i . j) in k do
         (message "%c %d" i j)
)

I tried this but failed. error message is "symbol's value is void k."


Solution

  • This code works:

    (let ((my-list [((a . 1) (b . 2)) ((c . 3))]))
        (cl-loop for k across my-list do
            (cl-loop for (i . j) in k do
                (message "%s %d" i j))))
    

    (my-list is a vector of lists, not a list)

    Some tips to keep in mind:

    1. Literal Vectors vs. Lists: When declaring a literal vector, use square brackets [] without quotation:

      (equal '[1 2 3] [1 2 3]) ;; => t

    2. When using cl-loop, use the across keyword for vectors, not in: (cl-loop for k across my-list do ...)

    3. Lisp symbols vs. characters: In Lisp, symbols are different from characters. If you want to use characters (like the char type in C), use the ? notation:

      (message "%c" ?A) ;; => A

    So, your vector should look like this:

    (setq my-list [((?a . 1) (?b . 2)) ((?c . 3))])
    

    When printing Lisp symbols, use the %s format specification:

    (message "%s" 'hello)
    ;; => hello
    
    1. Lisp Symbols as Variables and Values: Lisp symbols can be used both as variable names and as values. For example:
    (setq my-var 'other-symbol)
    (setq other-symbol 1)
    (symbol-value my-var)
    ;; => 1