Re: Accessing JSON Array data in Clojure

1,359 views
Skip to first unread message

Michael Klishin

unread,
May 7, 2013, 12:27:01 PM5/7/13
to clo...@googlegroups.com

2013/5/7 Hawkeye02 <bryan.d....@gmail.com>
I can't get the data from inside the JSON arrays from Clojure.  Specifically, I looking to get the data from the "currently" array taken from this Dark Sky data:

Sorry but your JSON document example does not have arrays. Do you mean nested objects (maps)?

Parsed JSON documents are returned as Clojure maps. In your example, the issue seems to be that keys in the map
you have a strings but you are trying to access them as keywords. clojure.core/get-in is what I'd use instead [3].

And please don't use clojure.contrib.* stuff. Monolithic contrib has been deprecated a couple of years ago and is no longer
maintained. Use Cheshire [1] or data.json (I don't recommend this one) [2].

Finally, take a look at http://clojure-doc.org if you need a free beginner documentation resource.

Hawkeye02

unread,
May 7, 2013, 5:07:42 PM5/7/13
to clo...@googlegroups.com
Michael,

Thank you for the response and references.  I will try your suggestions and get back to you.  My terminology isn't the best, thanks for deciphering.  

greg r

unread,
May 7, 2013, 9:10:02 PM5/7/13
to clo...@googlegroups.com
You might want to check out "Clojure Data Analysis Handbook" by Eric Rochester.  There is an example using org.clojure/data.json and Incanter to read JSON format into an Incanter dataset.  You might find other recipes in the book useful as well:

http://www.packtpub.com/clojure-data-analysis-cookbook/book

I'm going through it (slowly) and learning a lot.  It's not a beginner's book.  Full blast functional programming for sure.

Regards,
Greg

Hawkeye02

unread,
May 9, 2013, 5:10:44 PM5/9/13
to clo...@googlegroups.com
Thanks Greg for the suggestion.  I have added the book to my Safari account.

Michael, I tried your suggestion with 'get-in' and it came back with [object Object] from JSON.  I switched the clojure.contrib stuff with data.json.

Below is the updated code and a screenshot of the result.  Thanks in advance for any guidance.

(ns brainiac.plugins.dark-sky
  (:require [brainiac.plugin :as brainiac]
            [clojure.data.json :as json]
            [clojure.java.io :as io :only (reader)]
            [clojure.core :as core]))


(defn format-forecast [forecast]
  {
    :temp (:currentTemp forecast)
    :current-summary (:currentSummary forecast)
    :hour-summary (core/get-in :dayPrecipitation [:temp] forecast)
    :minutes-until-change (:minutesUntilChange forecast)
  })

(defn transform [stream]
  (let [json (json/read-json (io/reader stream))]
    (assoc {}
      :name "dark-sky"
      :title "Right now, outside..."
      :data (format-forecast json))))

(defn url [api-key lat lon]

(defn configure [{:keys [api-key lat lon program-name]}]
  (brainiac/simple-http-plugin
    {:url (url api-key lat lon)}
    transform program-name))

Hawkeye02

unread,
May 9, 2013, 5:15:40 PM5/9/13
to clo...@googlegroups.com
Forgot to put the JSON data:

"radarStation":"lot","dayPrecipitation":[{"time":1368129600,"probability":0.23,"type":"rain","temp":74,"cloudCover":1,"relHumidity":0.45},......

Michael Klishin

unread,
May 9, 2013, 7:17:17 PM5/9/13
to clo...@googlegroups.com

2013/5/10 Hawkeye02 <bryan.d....@gmail.com>

:hour-summary (core/get-in :dayPrecipitation [:temp] forecast)

I don't think you use get-in the way it is demonstrated in the examples. It takes a map
as the first argument and a collection of keys to traverse.

http://clojuredocs.org/clojure_core/clojure.core/get-in

Also, you don't need to require clojure.core. It is automatically loaded and referred to.

Bryan Henderson

unread,
May 9, 2013, 10:27:53 PM5/9/13
to clo...@googlegroups.com
What map would be defined for the first argument with the given code?  It seems like how it is set up, it is grabbing information straight from the JSON data without a map defined.  The 'format-forecast' definition takes forecast as an arg so I tried it like this with no luck:

:hour-summary (core/get-in forecast [:dayPrecipitation :temp])

I wasn't sure what else to put for the first argument.

Thanks for the heads up on the clojure.core requirement.  I saw it in some other code online; figured I needed it.

Also, thanks again for the help.

 


--
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/ZreY5nWg0e4/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Michael Klishin

unread,
May 10, 2013, 5:54:54 AM5/10/13
to clo...@googlegroups.com

2013/5/10 Bryan Henderson <bryan.d....@gmail.com>

What map would be defined for the first argument with the given code?  It seems like how it is set up, it is grabbing information straight from the JSON data without a map defined.

Parsed JSON
 
 The 'format-forecast' definition takes forecast as an arg so I tried it like this with no luck:

:hour-summary (core/get-in forecast [:dayPrecipitation :temp])


I don't know what "no luck" means exactly but you are using keywords again while your map contains
strings as keys. "time" is not the same as :time.

Here's the time of the first precipitation, in a REPL session:

Thomas Heller

unread,
May 10, 2013, 5:57:20 AM5/10/13
to clo...@googlegroups.com
Hey,

I only glanced over the discussion, but I think you have a type problem. Keyword vs. Strings to be precise, the JSON data you pasted will not convert to keyword keys by default I think.

So instead of (core/get-in forecast [:dayPrecipitation :temp])

try (core/get-in forecast ["dayPrecipitation" "temp"])

HTH,
/thomas
Reply all
Reply to author
Forward
0 new messages