I need to locate a particular value that can be buried into a deeply nested list, and never at the same place. Or even the same depth ; Here is one form of the list:
(setq my-list '(((partnum . 1) (type (TEXT . plain)) (body (charset UTF-8))
(disposition nil) (transfer-encoding QUOTED-PRINTABLE))
((partnum . 2) (type (TEXT . html)) (body (charset UTF-8))
(disposition nil) (transfer-encoding QUOTED-PRINTABLE))))
Now I need to retrieve the value of "charset" ; The first one if any. In this very configuration, it's easy:
(car (cdr (cadr (third (car my-list)))))
=> UTF-8
But this is when I know exactly where the "body" cell is.
I tried to use mapcar recursively like this :
(defun search-rec (list)
(mapcar
(lambda (x)
(if (listp x)
(search-rec x)
(message "OY %s" x)))
list))
but every time, I get the error (wrong-type-argument listp 1) when the recursion hits the first atom of the first cons cell. I guess my question really is what it is :
How can I search in a list?
EDIT Now the list looks like this, "charset" is still in (body) (told you that was about the only constant thing) and it's no longer found :(
(setq my-list '(((partnum . 1)
(1.1 (type (TEXT . plain)) (body (charset UTF-8))
(disposition nil) (transfer-encoding 7BIT))
(1.2 (type (TEXT . html)) (body (charset UTF-8))
(disposition nil) (transfer-encoding 7BIT))
(type . alternative) (body (boundary e89a8fb2067eba300404c63c5f7f))
(disposition nil) (transfer-encoding nil))
((partnum . 1.1) (type (TEXT . plain)) (body (charset UTF-8))
(disposition nil) (transfer-encoding 7BIT))
((partnum . 1.2) (type (TEXT . html)) (body (charset UTF-8))
(disposition nil) (transfer-encoding 7BIT))
((partnum . 2) (type (IMAGE . x-xpixmap)) (body (name ladybug.xpm))
(disposition nil) (transfer-encoding BASE64))))
EDIT here is some more IRL example:
(setq my-list haystack-list)
(setq my-needle (tree-assoc 'charset my-list))
(message "
-------------\n
- my-list: %s\n
- my-needle: %s\n
-------------\n" my-list my-needle)
Produces:
my-list: ((TEXT plain (charset UTF-8) nil nil 7BIT 260 18 nil nil nil) (TEXT html (charset UTF-8) nil nil QUOTED-PRINTABLE 738 17 nil nil nil) alternative (boundary e89a8fb1f8061a6be404c70a24a0) nil nil)
my-needle: nil
When on the other hand:
(tree-assoc 'charset '((TEXT plain (charset UTF-8) nil nil 7BIT 260 18 nil nil nil)
(TEXT html (charset UTF-8) nil nil QUOTED-PRINTABLE 738 17 nil nil nil)
alternative (boundary e89a8fb1f8061a6be404c70a24a0) nil nil))
=>(charset UTF-8)
So really, I don't know what's going on here : One could argue "what is this haystack-list and where does it come from?" But is it relevant ? I'm working on a copy (my-list) of this haystack-list so what gives those different results ? The quoting of the list ? Guys, I'm really lost
NB (This behaviour (Works in a direct eval, but not in a defun/let production situation) occurred with all the solution given)
EDIT: I ended up extracting the first list found, and then extracting (not searching) elements from that list. I proved faster ; Of course this is when you can say "my element is always in the fist list found) ; thanks to everybody, I learned a lot through all this.