2024 Clojure 状态调查!分享你的想法。

欢迎!请访问关于页面了解更多有关如何使用本服务的详细信息。

0票数
Clojure

你好,Clojurians,我在填充数字数组的最佳实践方面有一个问题。

这不是一个序列结构。我指的是数学序列,例如,1, 2, 3, 4, 5, 6, 7, ..., n

我的背景是统计编程,因此生成数字列表是非常常见且有用的!

在 R 语言中,要生成数字数组,你可以这样做

seq(1, 10) => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

或者缩写为

1:10 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

以上两种方式都被认为是经典的,因为它们既易读又快。

然后将数组赋值给一个变量

nums = seq(1, 10)
nums => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

那么 Clojure 怎样做这件事呢?

不幸的是,我在网上搜索解决方案时遇到了麻烦,因为不可避免地,任何包含“序列”的搜索都会带来https://docs.clojure.org/clojure.core/seq

1 个答案

+1票数
 
最佳答案

你应该使用范围(range)函数。

(range 10)
; => (0 1 2 3 4 5 6 7 8 9)
非常感谢!
如果要在这个情况下实现一个具有O(1)访问索引的数据结构(持久化)以完成答案,可以将`range`的结果压入向量中。

(vec (range 10))

或者,如果您需要一个实际可变的数组,

(long-array (range 10))

向量是一种习惯性的“持久化数组列表”。如果您做了很多随机访问或更新,向量在实践中的表现将远远优于序列,因为序列获取第n个元素是O(n)的(列表性能),而且它们不像向量支持“关联”函数那样直接支持更新操作。

从数学的角度来看,“这不是seq结构。我指的是数学序列,例如,1,2,3,4,5,6,7,...,n”,在Clojure中相当没有意义,因为所有集合或可迭代对象都是可序列的。例如,您可以随意处理无限序列,并只遍历或消费计算所需的部分。通常以这种方式定义算法(生成所有可能的解决方案可能的无限序列,然后过滤该序列,从中取值,丢弃项,映射到它,等等,直到找到结果)。您还可以定义生成函数(例如,通过`iterate`或使用`lazy-seq`的较低级实现)。在https://clojure.github.io/math.combinatorics/中有大量有趣的生成函数。
尽管原来的答案已经足够,但我偶尔使用(vec (range ...)),正如你描述的原因。

如果我为ask.clojure.org启用了电子邮件更新,我就会看到你的评论,也可能节省一些麻烦。我现在会这么做!

再次感谢。
...