1

I loaded some json data into a string and have elisp parsing it using the json-read-from-string function. Now I want to do is access data from the JSON by key. When I print out the data via message, it looks kind of like a list of lists (with arrays too!), so I assumed that the regular association list functions would work on the data, however this does not seem to be the case.

Here is a sample code that I am trying to debug:

(require 'request)
(require 'json)
(require 'cl)

(setq json-string "{\"1\": [{\"id\": 2,\"attribute\": \"salutation\",\"displayName\": \"Salutation\",\"category\": 1},{\"id\": 4,\"attribute\": \"middlename\",\"displayName\": \"Middle Name\",\"category\": 1},{\"id\": 6,\"attribute\": \"suffix\",\"displayName\": \"Suffix\",\"category\": 1},{\"id\": 8,\"attribute\": \"city\",\"displayName\": \"City\",\"category\": 1},{\"id\": 9,\"attribute\": \"state\",\"displayName\": \"State\",\"category\": 1},{\"id\": 11,\"attribute\": \"email\",\"displayName\": \"Email\",\"category\": 1},{\"id\": 12,\"attribute\": \"telephone\",\"displayName\": \"Telephone\",\"category\": 1},{\"id\": 10,\"attribute\": \"zipCode\",\"displayName\": \"Zip Code\",\"category\": 1},{\"id\": 13,\"attribute\": \"telephoneExtension\",\"displayName\": \"Telephone Extension\",\"category\": 1},{\"id\": 7,\"attribute\": \"streetAddress\",\"displayName\": \"Street Address\",\"category\": 1},{\"id\": 3,\"attribute\": \"firstName\",\"displayName\": \"First Name\",\"category\": 1},{\"id\": 1,\"attribute\": \"fullName\",\"displayName\": \"Full Name\",\"category\": 1},{\"id\": 5,\"attribute\": \"lastName\",\"displayName\": \"Last Name\",\"category\": 1},{\"id\": 14,\"attribute\": \"notes\",\"displayName\": \"Notes\",\"category\": 1}],\"2\": [{\"id\": 15,\"attribute\": \"name\",\"displayName\": \"Name\",\"category\": 2},{\"id\": 16,\"attribute\": \"address\",\"displayName\": \"Address\",\"category\": 2},{\"id\": 17,\"attribute\": \"phone\",\"displayName\": \"Phone\",\"category\": 2},{\"id\": 18,\"attribute\": \"email\",\"displayName\": \"email\",\"category\": 2},{\"id\": 19,\"attribute\": \"url\",\"displayName\": \"URL\",\"category\": 2}],\"3\": [{\"id\": 20,\"attribute\": \"name\",\"displayName\": \"Name\",\"category\": 3},{\"id\": 21,\"attribute\": \"address\",\"displayName\": \"address\",\"category\": 3},{\"id\": 22,\"attribute\": \"county\",\"displayName\": \"County\",\"category\": 3},{\"id\": 23,\"attribute\": \"state\",\"displayName\": \"State\",\"category\": 3},{\"id\": 24,\"attribute\": \"zipcode\",\"displayName\": \"Zip Code\",\"category\": 3},{\"id\": 25,\"attribute\": \"pin\",\"displayName\": \"PIN\",\"category\": 3},{\"id\": 26,\"attribute\": \"longitude\",\"displayName\": \"Longitude\",\"category\": 3},{\"id\": 27,\"attribute\": \"latitude\",\"displayName\": \"Latitude\",\"category\": 3}]")

(setq tester (json-read-from-string json-string))

;;(message "%s" tester)
;; This looks like: ((1 . [((id . 2) (attribute . salutation) (displayName . Salutation) (category . 1)) ((id . 4) (attribute . middlename) (displayName . Middle Name) (category . 1)) ((id . 6) (attribute . suffix) (displayName . Suffix) (category . 1)) ((id . 8) (attribute . city) (displayName . City) (category . 1)) ((id . 9) (attribute . state) (displayName . State) (category . 1)) ((id . 11) (attribute . email) (displayName . Email) (category . 1)) ((id . 12) (attribute . telephone) (displayName . Telephone) (category . 1)) ((id . 10) (attribute . zipCode) (displayName . Zip Code) (category . 1)) ((id . 13) (attribute . telephoneExtension) (displayName . Telephone Extension) (category . 1)) ((id . 7) (attribute . streetAddress) (displayName . Street Address) (category . 1)) ((id . 3) (attribute . firstName) (displayName . First Name) (category . 1)) ((id . 1) (attribute . fullName) (displayName . Full Name) (category . 1)) ((id . 5) (attribute . lastName) (displayName . Last Name) (category . 1)) ((id . 14) (attribute . notes) (displayName . Notes) (category . 1))]) (2 . [((id . 15) (attribute . name) (displayName . Name) (category . 2)) ((id . 16) (attribute . address) (displayName . Address) (category . 2)) ((id . 17) (attribute . phone) (displayName . Phone) (category . 2)) ((id . 18) (attribute . email) (displayName . email) (category . 2)) ((id . 19) (attribute . url) (displayName . URL) (category . 2))]) (3 . [((id . 20) (attribute . name) (displayName . Name) (category . 3)) ((id . 21) (attribute . address) (displayName . address) (category . 3)) ((id . 22) (attribute . county) (displayName . County) (category . 3)) ((id . 23) (attribute . state) (displayName . State) (category . 3)) ((id . 24) (attribute . zipcode) (displayName . Zip Code) (category . 3)) ((id . 25) (attribute . pin) (displayName . PIN) (category . 3)) ((id . 26) (attribute . longitude) (displayName . Longitude) (category . 3)) ((id . 27) (attribute . latitude) (displayName . Latitude) (category . 3))]))

(message "%s" (assoc '1 tester))
;; => nil

Using assoc, alist-get, assq all seem to return nil in the last line.

Is there a different function that I need to use? Or do I just have to loop through the data myself to find the data that I want?

1

Cute.

Take a look at the beginning of the alist again:

((1 . [((id . 2) (attribute . salutation)…

It looks like the key is a number, so I tried that

(assoc 1 tester)
nil

It doesn't have any quotes, but maybe a string?

(assoc "1" tester)
nil

Nope. It's actually a symbol whose name is the single digit 1:

(assoc '\1 tester)
(\1 . [((id . 2)…

When I printed out the whole tester object I also saw the \; I'm not sure why it's not printed that way in your example code. One thing that I like about Common Lisp is that symbols with unusual names get "quoted" with vertical bars; that would help a lot in this situation, since the keys would be |1|, |2|, etc.

  • 1
    Try message with %S. – politza Jul 21 '17 at 20:45
  • Thanks! That works. How would you go about storing '\1 inside a variable to pass into assoc? I have a integer in a variable, but I don't know how to convert that to the correct symbol. I tried: (setq id 1) (setq idsym (make-symbol (number-to-string id))) (message "%S" (assoc idsym tester)) to no avail. – chaseme Jul 26 '17 at 16:08
  • (setq id '\1) – db48x Jul 27 '17 at 0:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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