【问题标题】:Return an array from let using doseq and into使用doseq从let返回一个数组并进入
【发布时间】:2016-06-02 23:08:11
【问题描述】:

我正在尝试从 let 语句返回一个列表。

(let [data []]
 (doseq [x ["0" "1" "2" "3" "4"]]
  (into data (do-stuff x))) data)

但是data 列表始终为空。

我检查了this 从 let 范围返回值的答案,但无法解决此问题。

【问题讨论】:

  • data 是不可变的 - 如果您想返回 ["0" "1" "2" "3" "4"],您可以直接返回它,而不是尝试将其复制到新列表中。
  • 这只是一个例子,["0" "1" "2" "3" "4"] 是一个可以是任何列表的变量
  • 对,但是无论列表是什么,您都可以直接返回,因为它是不可变的。
  • 编辑了问题,我也需要在 x 上执行功能

标签: clojure


【解决方案1】:

如果您想了解 Clojure 中的循环机制,您可能正在寻找这个(假设您所做的只是对集合如何工作的练习):

(for [x ["1" "2" "3"]] x)

结果是:

("1" "2" "3")

当然,如果这就是您要做的全部,那么您已经拥有该集合,无需构建它。

根据您的编辑,执行以下操作:

(for [x ["1" "2" "3"]] (do-stuff x))

不过,还有许多其他方法可以执行此类操作,例如使用 mapreduce 和其他工具,具体取决于 do-stuff 的复杂性以及它需要访问的内容。

请记住,Clojure 中的值默认是不可变的。您根本无法改变您的data,它的值固定为[]。除非您将其设为 atom,否则对于您的需要来说这是不必要的。函数式编程是关于建立价值,而不是改变变量。

有很多方法可以表达您想要做的事情,但fordo-seq 的列表构建(“列表理解”)版本,因为它们具有相同的一般结构。由于您的问题是关于do-seq,因此我讨论for 以获得良好的衡量标准。但是map 在这里是一个更好的选择。如果你真的需要它是一个向量而不是一个惰性序列,那么使用mapv

如果您需要一个名为 data 的东西来保存这些结果,那么只需这样做:

(let [data (for [x ["1" "2" "3"]] x)] ;;or map, etc
   ;;do something with data
 )

【讨论】:

    【解决方案2】:

    如果你想修改每个元素并返回一个向量你可以使用mapv:

    (mapv do-stuff ["0" "1" "2" "3" "4"])
    

    如果您只需要序列输出,也可以使用map

    (map do-stuff ["0" "1" "2" "3" "4"])
    

    或for表达式:

    (for [x ["0" "1" "2" "3" "4"]] (do-stuff x))
    

    for 表达式返回一个序列,如果需要,您可以使用vec 将其转换为向量:

    (vec (for [x ["0" "1" "2" "3" "4"]] (do-stuff x)))
    

    【讨论】:

      猜你喜欢
      • 2020-12-10
      • 1970-01-01
      • 2019-12-19
      • 1970-01-01
      • 2021-03-16
      • 2022-01-13
      • 1970-01-01
      • 2013-03-11
      • 2012-08-21
      相关资源
      最近更新 更多