Clojure 与 reduce 相反?

Clojure opposite of reduce?

我 运行 经常关注这个问题(在 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 ... )) 不理想。

怎么样:

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

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

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

(这里使用 mapvmap 是无所谓的。)

(另外,reduce的"opposite"在其他语言中通常被称为unfold,但我还没有在核心Clojure库中找到类似的功能。)

cons 在这里很好——它从 Lisp 诞生之初就存在了,它对你在这里想做的事情很有用。

以下是我的处理方法:

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

"opposite of reduce"减少了。

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

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

我想如果你把 (mapv f coll) 改成

(map f coll)

(doall (map f coll))

您会得到想要的结果。