Fork me on GitHub
#beginners
<
2016-05-28
>
dmbennett14:05:17

Hey folks, is there a good resources for how to grab specific data from complex json structures that contains a vector of hashes?

dmbennett14:05:26

I’ve been trying to extract data from a rest response for a while and have hit a wall when it comes to filtering out elements of a vector that contain a hash that don’t contain what I want

val_waeselynck16:05:04

@dmbennett it's hard to tell where you're stuck better give us an example

bwstearns17:05:11

@dmbennett: if I'm reading you right your rest response looks something like

(def response {:response 
               {:foos [{:id 1 :fooname "Bar" :fooval "foo values"}
                       {:id 2 :fooname "Baz" :fooval "Baz values"}
                       ......... more records]}})
If that's the case then you probably want to map over list of hashes to start. something like
(def my-foos (get-in response [:response :foos])) ;; this gets you just your map of hashes
(def foo-vals (map :fooval my-foos)) ;; from that it's easy to map over your list of maps to extract values
(def filtered-foos (filter (fn [x] (even? (:id x))) my-foos)) ;; use filter with a predicate to limit the records returned
I know for extremely large chunks of data there may be better ways, but for the size of json you typically run into life gets a lot easier to just def (or using let bindings of course if you're doing this in a function) new views into the larger data structure. If you look at the contrived example above to get all the foo-vals you can see that my-foos handles the navigation to the data you want, and then the map function extracts the relevant data.

dmbennett17:05:53

@bwstearns: thanks for the response.

dmbennett17:05:23

I think I’m running into some trouble around the filter-foos part

dmbennett17:05:00

foo-vals returns a lazy seq?

bwstearns17:05:18

oh yeah, you might want mapv

dmbennett17:05:20

but I’m not sure how to iterate over them

dmbennett17:05:41

how does the type change?

bwstearns17:05:56

mapv returns a vector instead of a lazy seq

bwstearns18:05:24

I think there is also a filterv? (looking now)

bwstearns18:05:54

example

user=> (map #(* 2 %) (range 1 10))
(2 4 6 8 10 12 14 16 18)
user=> (mapv #(* 2 %) (range 1 10))
[2 4 6 8 10 12 14 16 18]

dmbennett18:05:40

I’ll try that out

bwstearns18:05:49

is your problem that you're getting errors?

dmbennett18:05:08

type errors usually

dmbennett18:05:28

and also I’m having a hard time understanding the function that I want to call on every vector element

bwstearns18:05:43

So I'm not sure what workflows you're used to, but for data munging I find it really helpful to just spin up a repl, slurp in the data and build functions in the repl iteratively and only bother actually saving the ones that work the way I want

dmbennett18:05:01

I’ve been doing that

dmbennett18:05:08

give me a sec I’ll grab the json for you

bwstearns18:05:26

Let's move to #C1CGD283U to not totally overrun the beginners channel

dmbennett18:05:26

Of the histories, I need to check each item for the values :field “status” and return the entire item

dmbennett20:05:26

What does the error java.lang.NullPointerException mean

sveri21:05:12

@dmbennett: That means that you tried to access an object that is null. Something like:

Car c = null;
c.isStarted(); ->NPE

samuelf23:05:36

Hi, those this is indirectly about Closure but I’m experimenting with state and mutation in other languages to get a feel for the problems that Clojure solves and why its solutions are the way that they are. I know that among the goals of referential transparency is to have something like AssertEqual(f(x) : f(x)) always pass. If it doesn’t there is some evil side-effect or mutation lurking in the background. So I wrote some Ruby to cause this problem.

samuelf23:05:38

I expected the second statement to return false but it returned true.

samuelf23:05:46

#push returns the state of the array after the push so the left side should come out [1] and the right side to [1, 1].

maxov23:05:22

@samuelf: in ruby (and many other languages) == is an identity comparison, not an equality comparison

maxov23:05:12

#push returns the array, which retains the same identity