替代品与dotimes相同,但会返回除nil之外的其他内容

时间:2018-02-26 16:02:36

标签: vector clojure

我需要类似于clojure中的dotimes,但是我会在最后返回一些东西而不是nil。我自己没有找到任何东西,但需要它能够接收一个向量,对每个元素进行一些格式化,然后将该元素集中到一个新的向量上。任何帮助都会很棒。感谢

(defn single-in-vec [num]
  (if (symbol? num)
      (into [] (cons num ()))
       num)
 )


(defn add-in-vec [tree newtree]
  (dotimes [n 5] (cons  (single-in-vec (nth tree n)) newtree ))
  newtree) 

这就是我输入的内容。

(add-in-vec '[A B C [D E F] [G H I]] '[ ])

这是预期的输出

[[A] [B] [C] [D E F] [G H I]]

2 个答案:

答案 0 :(得分:2)

您应该使用类似reduce的内容:

(defn single-in-vec [num]
  (if (symbol? num)
    (into [] (cons num ()))
    num))

(defn add-in-vec [tree newtree]
  (reduce (fn [acc elem]
            (conj acc (single-in-vec (nth tree elem)) ))
          newtree
          (range 5)))

(add-in-vec '[A B C [D E F] [G H I]] '[])
=> [[A] [B] [C] [D E F] [G H I]]

让我们回顾一下您原始示例中的一些问题:

(defn add-in-vec [tree newtree]
  (dotimes [n 5] (cons  (single-in-vec (nth tree n)) newtree ))
  newtree)
  1. dotimes通常用于副作用,但您不需要此处。您只想更新newtree五次并返回其最终状态。
  2. 最终返回值为newtree,但这始终是原始输入值,因为dotimes表单尚未对其进行变更。它的所有变化都已经消失了。
  3. cons将按照您想要的顺序生成输出。 conj将添加到向量的末尾。

答案 1 :(得分:1)

此外,您尝试做的事情是通过映射惯性完成的:

(defn wrap-sym [x]
  (if (symbol? x) [x] x))

user> (mapv wrap-sym '[A B C [D E F] [G H I]])
;;=> [[A] [B] [C] [D E F] [G H I]]

但首先你需要获得一些关于如何在clojure(以及函数式编程语言)中完成任务的正确介绍性阅读

我的建议是clojure for the brave and true