5

Say I have a list of names with ids, in JSON:

(let ((json-object-type 'plist))
  (setq mylist (json-read-from-string "[{\"name\": \"Adam\", \"id\": \"1\"},
                                        {\"name\": \"Eve\", \"id\": \"2\"}]")))

I want to find out Adam's id. How do I do that?

I'm currently trying

(dolist (person  mylist)
  (when (equal "Adam" (plist-get person :name))
    (setq person_id (plist-get person :id)))
  )

But this raises setq: Wrong type argument: listp, [(:id "1" :name "Adam") (:id "2" :name "Eve")]

4
  • 1
    You're passing a vector to a macro expecting a list...
    – wasamasa
    Jul 28, 2015 at 21:31
  • Thanks, that pointed me towards the easiest (read as 'minimal change') solution, just converting the vector to a list using (mapchar 'identity ...)
    – andreas-h
    Jul 28, 2015 at 22:27
  • The easiest way to do that would be (append vector nil).
    – wasamasa
    Jul 29, 2015 at 7:29
  • Could you add your own comment as a solution and/or accept one of the others if it worked for you?
    – Dan
    Sep 27, 2015 at 18:41

2 Answers 2

6

You can instruct json-read-from-string to parse JSON arrays as elisp lists by let binding json-array-type to list like so

(let ((json-object-type 'plist)
      (json-array-type 'list))
  (setq mylist (json-read-from-string "[{\"name\": \"Adam\", \"id\": \"1\"},
                                        {\"name\": \"Eve\", \"id\": \"2\"}]")))                                 {\"name\": \"Eve\", \"id\": \"2\"}]")))

mylist now would be an elisp list which you manipulate/traverse using existing list functions.

0

Working with vectors is a tad bothersome as only the most basic operations have been implemented. Here's a handcoded loop:

(let* ((json-object-type 'plist)
       (vector (json-read-from-string "[{\"name\": \"Adam\", \"id\": \"1\"},
                                        {\"name\": \"Eve\", \"id\": \"2\"}]"))
       (i 0)
       value)
  (while (and (< i (length vector)) (not value))
    (let ((person (aref vector i)))
      (when (string= (plist-get person :name) "Adam")
        (setq value (plist-get person :id))))
    (setq i (1+ i)))
  value)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.