【问题标题】:Clojure opposite of reduce?Clojure与reduce相反?
【发布时间】:2015-07-18 16:32:59
【问题描述】:

我经常遇到这个问题(在 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 ... )) 不理想。

【问题讨论】:

标签: clojure clojurescript


【解决方案1】:

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

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

(map f coll)

(doall (map f coll))

你会得到你正在寻找的结果。

【讨论】:

    【解决方案2】:

    reduce 的反义词是 reduce。

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

    【讨论】:

      【解决方案3】:

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

      以下是我的处理方法:

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

      【讨论】:

        【解决方案4】:

        怎么样:

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

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

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

        (这里使用mapvmap 将无所谓。)

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

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-22
        • 2019-07-18
        • 1970-01-01
        • 2020-06-28
        • 1970-01-01
        • 1970-01-01
        • 2016-08-29
        • 2022-09-15
        相关资源
        最近更新 更多