如何在循环 Clojure 中的第一个集合时合并两个集合的元素?
How do I merge the elements of two collections while cycling the first in Clojure?
如何优雅地接受这两个输入:
(def foo [:a 1 :a 1 :a 2])
(def bar [{:hi "there 1"}{:hi "there 2"}{:hi "there 3"}{:hi "there 4"}{:h1 "there 5"}])
并得到:
[{:hi "there 1" :a 1}{:hi "there 2" :a 1}{:hi "there 3" :a 2}{:hi "there 4" :a 1}{:hi "there 5" :a 1}]
第一次收集在第二次收集达到相同数量的元素时循环。第一个集合可以是这些中的任何一个,因为它将被硬编码:
(def foo [{:a 1} {:a 1} {:a 2}])
(def foo [[:a 1] [:a 1] [:a 2]])
(def foo [1 1 2])
可能还有另一种数据结构会更好。 1 1 2
是故意的,因为它不是 1 2 3
允许 range
或类似的东西。
循环浏览第一个集合很容易...我不确定如何同时浏览第二个集合。但我的做法可能一开始就不对。
像往常一样,我倾向于对命令式代码进行奇怪的嵌套模仿,但我知道有更好的方法!
这是一种方法:
您可以从 foo
中获取值,循环遍历它们并将它们一次分成 2 组。大小为 2 的向量有一个小秘密,那就是它们可以用作小地图(1 key/value 对)。
一旦我们有了两个地图集,我们就可以将它们合并在一起。一个集合是无限的,但没关系,map
将只计算值,直到一个集合用完所有元素。 mapv
与 map
相同,但它 returns 是一个向量。
(def foo [:a 1 :a 1 :a 2])
(def bar [{:hi "there 1"}{:hi "there 2"}{:hi "there 3"}{:hi "there 4"}{:h1 "there 5"}])
(defn cycle-and-zip [xs maps]
(let [xs-pairs (->> xs cycle (partition 2) (map vec))]
(mapv merge maps xs-pairs)))
(cycle-and-zip foo bar)
;; => [{:hi "there 1", :a 1} {:hi "there 2", :a 1} {:hi "there 3", :a 2} {:hi "there 4", :a 1} {:h1 "there 5", :a 1}]
更新:将 map
替换为 mapv
,因此输出实际上是一个向量。
(def foo [{:a 1} {:a 1} {:a 2}])
(def bar [{:hi "there 1"}{:hi "there 2"}{:hi "there 3"}{:hi "there 4"}{:h1 "there 5"}])
(mapv merge (cycle foo) bar)
如何优雅地接受这两个输入:
(def foo [:a 1 :a 1 :a 2])
(def bar [{:hi "there 1"}{:hi "there 2"}{:hi "there 3"}{:hi "there 4"}{:h1 "there 5"}])
并得到:
[{:hi "there 1" :a 1}{:hi "there 2" :a 1}{:hi "there 3" :a 2}{:hi "there 4" :a 1}{:hi "there 5" :a 1}]
第一次收集在第二次收集达到相同数量的元素时循环。第一个集合可以是这些中的任何一个,因为它将被硬编码:
(def foo [{:a 1} {:a 1} {:a 2}])
(def foo [[:a 1] [:a 1] [:a 2]])
(def foo [1 1 2])
可能还有另一种数据结构会更好。 1 1 2
是故意的,因为它不是 1 2 3
允许 range
或类似的东西。
循环浏览第一个集合很容易...我不确定如何同时浏览第二个集合。但我的做法可能一开始就不对。
像往常一样,我倾向于对命令式代码进行奇怪的嵌套模仿,但我知道有更好的方法!
这是一种方法:
您可以从 foo
中获取值,循环遍历它们并将它们一次分成 2 组。大小为 2 的向量有一个小秘密,那就是它们可以用作小地图(1 key/value 对)。
一旦我们有了两个地图集,我们就可以将它们合并在一起。一个集合是无限的,但没关系,map
将只计算值,直到一个集合用完所有元素。 mapv
与 map
相同,但它 returns 是一个向量。
(def foo [:a 1 :a 1 :a 2])
(def bar [{:hi "there 1"}{:hi "there 2"}{:hi "there 3"}{:hi "there 4"}{:h1 "there 5"}])
(defn cycle-and-zip [xs maps]
(let [xs-pairs (->> xs cycle (partition 2) (map vec))]
(mapv merge maps xs-pairs)))
(cycle-and-zip foo bar)
;; => [{:hi "there 1", :a 1} {:hi "there 2", :a 1} {:hi "there 3", :a 2} {:hi "there 4", :a 1} {:h1 "there 5", :a 1}]
更新:将 map
替换为 mapv
,因此输出实际上是一个向量。
(def foo [{:a 1} {:a 1} {:a 2}])
(def bar [{:hi "there 1"}{:hi "there 2"}{:hi "there 3"}{:hi "there 4"}{:h1 "there 5"}])
(mapv merge (cycle foo) bar)