Clojure与reduce相反?

时间:2015-05-07 21:51:53

标签: clojure clojurescript

我经常遇到这个问题(更常见于clojurescript),但没有注意到其他人如何处理它。这就是我想要的:

[:div.container [:div.first "first"] [:div.second "second"] [:div.third "third"]]

让我们说我是从像["first" "second" "third"]

这样的集合中构建它的

我将通过mapv传递集合并结束(此代码是草图,我没有使用它):

(mapv
  #([(keyword (str "div." %)) %])
  ["first" "second" "third"])
=> [[:div.first "first"] [:div.second "second"] [:div.third "third"]]

如果我在容器div中使用它,我会得到:

[:div.container [[:div.first "first"] [:div.second "second"] [:div.third "third"]]]

我一直在使用cons之类的内容将:div.container置于mapv结果的前面。但在我看来,应该有更好的方式 - 就像reduce的反面。有这样的事吗?

编辑:我确实找到了concat,看起来我之前尝试过,但我得到了一个序列。我想要一个矢量。 (vec (concat ... ))并不理想。

4 个答案:

答案 0 :(得分:3)

怎么样:

 (apply vector :div.container 
               (mapv #(vector (keyword (str "div." %)) %) 
                     ["first", "second", "third"]))

我们的想法是使用applymapv结果的每个元素作为单个参数传递给vector

作为奖励,apply在收集参数之前允许其他参数,因此我们可以将:div.container存放在那里。

(此处使用mapvmap无关。)

(另外,reduce的"对面"在其他语言中通常称为unfold,但我没有在核心Clojure库中找到类似函数。)

答案 1 :(得分:1)

cons在这里很好 - 它自Lisp诞生以来一直存在,它对你想要在这里做什么很有用。

以下是我如何做到这一点:

(defn containerize
  [tag v]
  (let [kw #(keyword (str tag "." %))]
    (into [] 
      (cons (kw "container")
        (map (fn [x] [(kw x) x]) v)))))

答案 2 :(得分:1)

“减少对面”是减少。

(reduce (fn [v s]
          (conj v [(keyword (str "div." s)) s]))
        [:div.container]
        ["first" "second" "third"])

答案 3 :(得分:0)

你知道[:ul([:li" one"] [:li" two"])]会按预期工作吗?

我想如果你改变(mapv f coll)到

(map f coll)

(doall (map f coll))

您将获得您正在寻找的结果。