Вектор карт из списков

Как бы я получил следующее:

[{:foo "a" :bar "b" :biz "c"}
 {:foo "d" :bar "e" :biz "f"}
 {:foo "h" :bar "i" :biz "j"}]

от

("a" "d" "h")
("b" "e" "i")
("c" "f" "j")

Заранее спасибо!


person THX1137    schedule 12.02.2018    source источник


Ответы (3)


Вы можете транспонировать ввод с помощью map и zipmap для создания карт результатов:

(def input ['("a" "d" "h")
            '("b" "e" "i")
            '("c" "f" "j")])

(mapv #(zipmap [:foo :bar :biz] %) (apply map vector input))
person Lee    schedule 12.02.2018
comment
Благодарю вас! Это кратко и полезно. - person THX1137; 13.02.2018

это очень похоже на вариант @lee, но делает это за один проход, используя способность clojure map работать с несколькими коллекциями:

(def input ['("a" "d" "h")
            '("b" "e" "i")
            '("c" "f" "j")])

(apply mapv #(zipmap [:foo :bar :biz] %&) input)
;;=> [{:foo "a", :bar "b", :biz "c"} 
;;    {:foo "d", :bar "e", :biz "f"} 
;;    {:foo "h", :bar "i", :biz "j"}]
person leetwinski    schedule 13.02.2018

map может работать с несколькими последовательностями. Когда задано несколько последовательностей, он будет брать элементы из каждой и вызывать вашу функцию с ними следующим образом:

(let [s1 '("a" "d" "h")
      s2 '("b" "e" "i")
      s3 '("c" "f" "j")]
  (map (fn [x y z]
         {:foo x :bar y :baz z})
       s1 s2 s3))
;; =>
({:foo "a", :bar "b", :baz "c"}
 {:foo "d", :bar "e", :baz "f"}
 {:foo "h", :bar "i", :baz "j"})
person dpsutton    schedule 12.02.2018
comment
Это также круто, так как использует еще больше основных строительных блоков. Спасибо! - person THX1137; 13.02.2018