Fork me on GitHub
#beginners
<
2018-10-11
>
rakhim07:10:00

Hi all, I'm constructing a vector using a map like so

(mapv #(let [ {:keys [a b c]} %]
          [b c "foo" a]
          ) data)
I need to add a counter, so that the resulting vector looks like this:
[
  [1 b c "foo" a]
  [2 b c "foo" a]
  [3 b c "foo" a]
  ...
]
Is there an elegant way to achieve this without using loop/recur/var?

henrik11:10:55

Check out map-indexed also. I usually do indexing with (map-indexed vector …)

henrik11:10:12

Sorry, I saw that this was already suggested below.

rakhim11:10:46

thanks anyway!

schmee07:10:01

yes, something like mapv your-fn data (range)

schmee07:10:18

now your-fn gets two arguments, the map and the index

schmee07:10:47

user=> (mapv (fn [m i] [(:a m) (inc i)]) [{:a "a"} {:a "b"}] (range))
[["a" 1] ["b" 2]]

rakhim07:10:49

woah, yeah! prefect! thank you!

rakhim07:10:17

My imperative brain started thinking about maintaining a counter variable...

schmee07:10:46

but you stopped yourself before it was too late! 😄

rakhim07:10:07

The struggle is real 😄

lispyclouds07:10:52

@rakhim you can also use map-indexed too (map-indexed (fn [i m] [(:a m) (inc i)]) [{:a "a"} {:a "b"}])

lispyclouds07:10:01

produces the same effect

rakhim07:10:30

Wait... but why?.. (range) returns a lazy seq, and then... (inc i), I don't quite understand how this works

orestis08:10:31

I think (inc i) is only there to go from 0 1 2 to 1 2 3 since (range) starts with 0.

rakhim08:10:37

Yeah, got it, this tripped me up at first. Thank you!

rakhim07:10:22

I wonder how come mapv ever stops since (range) is infinite?

lispyclouds07:10:32

you are passing 2 args to map: [{:a "a"} {:a "b"}] and (range). so map runs till one of them finishes. in this case its the first param

rakhim07:10:58

@rahul080327 thanks, this is even better, although requires an into or something to convert it to a vector since there's no mapv-indexed

lispyclouds07:10:18

yeah thats a catch

petr.mensik10:10:38

How can it be that this tests comparing two numbers fails?

expected: 3 to be an instance of java.lang.Long
was: 3 is an instance of java.lang.Integer
       [praha bRno]

      (testing "case insensitive"
        (let [xs (contacts/get-all {:city ["praha" "bRno"] :lang_id "cs"})]
          (is (= 2 (count xs)))
Is there a way how to make clojure test ignore types or do I really need cast the int to long?

danm10:10:41

boot.user=> (is (= (Long. 2) (Integer. 2)))
true
What is contacts/get-all returning...?

petr.mensik11:10:23

@carr0t it's a list of maps

danm11:10:54

boot.user=> (require '[clojure.test :refer :all])
nil
boot.user=> (is (= 2 (count '({:a "a"} {:b "b"}))))
true
boot.user=> (is (= 2 (count [{:a "a"} {:b "b"}])))
true
boot.user=> (is (= (Long. 2) (count '({:a "a"} {:b "b"}))))
true
boot.user=> (is (= (Integer. 2) (count '({:a "a"} {:b "b"}))))
true

danm11:10:58

No idea what's happening with your one... Are you using clojure.spec or is the newer version of clojure.test? Might be that the specfile somewhere is saying that the compared value must be a Long

juan_18:10:51

How do you parse JSON using multiple values in Json?

noisesmith18:10:20

@cpfiro are you asking how to parse json?

juan_18:10:08

@noisesmith yes but using two keys to pull out two values

noisesmith18:10:40

usually with jvm clojure I would parse first (using the cheshire library, or clojure.data.json), and then pull the keys out of the resulting map

noisesmith18:10:15

unless you are talking about cljs, where I would use the built in JSON class for interop

juan_18:10:11

Oh I meant values

juan_18:10:16

(((get_url_response url) :body) :offset ))

juan_18:10:31

but instead of just pulling out offset value, to pull offset and limit values

juan_18:10:46

exampe : {:limit 2, :offset 0, :total 7439, :more true}

noisesmith18:10:57

right, so you can use select-keys once you have a map

noisesmith18:10:09

but that's not json any more, it's just clojure data

noisesmith18:10:40

user=> (select-keys {:a 0 :b 1 :c "more"} [:a :b])
{:a 0, :b 1}

noisesmith18:10:00

often your http lib will convert the json for you

juan_18:10:37

ah, thank you

juan_18:10:55

select-keys is exactly what I was hoping for, thank you!