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")]

  • 1
    You're passing a vector to a macro expecting a list... – wasamasa Jul 28 '15 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 '15 at 22:27
  • The easiest way to do that would be (append vector nil). – wasamasa Jul 29 '15 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 '15 at 18:41

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.

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

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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