Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple lazy sequences into a map

Tags:

clojure

Given the keys

:id
:tag
:name

and three lazy sequences producing output in the form

(id1 id2 id3 ...)
(name1 name2 name3 ...)
(type1 type2 type3 ...)

what do I have to do do get a sequence of maps in the form

({id: id1 :name name1 :type type1}
{id: id2 :name name2 :type type2}
{id: id3 :name name3 :type type3}
...)

I tried various combinations of apply, map, assoc etc but didn't get it.

like image 333
mmoehring Avatar asked Dec 02 '22 21:12

mmoehring


2 Answers

You only need map:

(map (fn [id name type] {:id id :name name :type type})
     (id1 id2 id3 ...)
     (name1 name2 name3 ...)
     (type1 type2 type3 ...))
like image 71
mtyaka Avatar answered Dec 19 '22 04:12

mtyaka


My answer is very similar to mtyaka's answer, but it is ever so slightly shorter, and more modular, in my opinion.

(map (fn [& vs] (zipmap [:id :name :type] vs))
     (id1 id2 id3 ...)
     (name1 name2 name3 ...)
     (type1 type2 type3 ...))

Here, zipmap is creating maps using a fixed key sequence and a variable value sequence, which during the "first step" will be (id1 name1 type1), during the "second step" will be (id2 name2 type2) etc.

This will only work if your three lazy sequences are isolated from one another. If you have a sequence of lazy sequences, i.e. ((id1 id2 ...) (name1 name2 ...) (type1 type2 ...)), then you will have to apply the above to this seq, like so:

(apply map (fn [& vs] (zipmap [:id :name :type] vs))
       ((id1 id2 id3 ...)
        (name1 name2 name3 ...)
        (type1 type2 type3 ..)))

Here, apply is simply prepending the code map (fn [& vs] (zipmap [:id :name :type] vs)) onto the front of the sequence of lazy sequences, and that becomes an expression to be evaluated. In other words, it is resulting in the exact same expression as the first block of code.

like image 23
Omri Bernstein Avatar answered Dec 19 '22 02:12

Omri Bernstein