0
votes

I'm trying to fill a Clojure vector with values from a map. I have another vector of specific keys in the map the store the values I need. I need to iterate the key-vec, get the values from the map and store them in another vector.

I've tried using loop+recur:

(let [keys-vec (:keys-vec item)
      my-map (:my-map item)]

   (loop [newV []
          i 0]
      (if (< i (count keys-vec))
        (recur
          (conj newV (get my-map (get keys-vec i)))
          (inc i))

         newV)))

And it worked. But I know Clojure is known for it's minimalistic/efficient code writing style and I wanted to know whether there's a better way.

Any ideas?

3
Could you specify what is it you are trying to achieve? Doesn't (def new-vector existing-vector) solve the problem? - superkonduktr
I believe it's close to an anti-pattern in Clojure to iterate through a vector using loop and elements' indices, as Clojure's collections are immutable and persistent. Instead, you are encouraged to use reducing functions. The idiomatic way to fulfil the task would simply be (vals (select-keys my-map keys-vec)). - superkonduktr
You're right it worked. thanks! - Yam Bakshi

3 Answers

3
votes

I'd say, that the most idiomatic way will be to use original vector. I don't see any reason to explicitly clone an immutable datastructure.

2
votes

You want the select-keys function to extract only the keys of interest from your map. See: http://clojuredocs.org/clojure.core/select-keys

Then, use the vals function to extract all of the values from the filtered map:

> (def my-map {:a 1 :b 2 :c 3})
> (def my-keys [:a :b])
> (select-keys my-map my-keys)
{:a 1, :b 2}

> (def filtered-map (select-keys my-map my-keys))
> filtered-map
{:a 1, :b 2}

> (vals filtered-map)
(1 2)

You should keep a browser tab open to the Clojure Cheatsheet at all times. It is invaluable for finding the functions you want. Keep studying it repeatedly, as you'll keep finding new things for years. This is my favorite version:

http://jafingerhut.github.io/cheatsheet/clojuredocs/cheatsheet-tiptip-cdocs-summary.html

1
votes

Using Alan Thompson's example:

(def my-map {:a 1 :b 2 :c 3})
(def my-keys [:a :b])

... a simple and fast solution is

(mapv my-map my-keys)
;[1 2]

The alternative

(vals (select-keys my-map my-keys))
;(2 1)

... may not (and, in this case, does not) maintain the order given by my-keys.