ruby - 在 Ruby 中将迭代器转换为数组的单行器
问题描述
这必须是一个常见问题解答,但经过大量网络搜索,我未能找到答案。我是 Ruby 编程语言的新手,所以我可能误解了一些基本的东西,或者我正在将我的 C#、F# 或 Haskell 知识投射到 Ruby 上。
如果我有类似以下的方法,是否有一种方法可以将其转换为数组或其他可变数据结构?
def foo
yield 8
yield 2
yield 5
end
我知道我可以这样做:
ary = Array.new
foo { |x| ary << x }
然而,这不是单行的。例如,在 C# 中,我可以使用ToList
或ToArray
扩展方法,或者在 F# 中,例如Seq.toList
:
let foo = seq {
yield 8
yield 2
yield 5
}
let arr = foo |> Seq.toList
Ruby 中是否有类似的单行代码?
还是我完全误解了 的本质foo
?
解决方案
实际上,您的问题中有两个独立的问题。
第一个问题在标题中:
在 Ruby 中将迭代器转换为数组的单行器
这很简单:Enumerator
,这是在 Ruby 中调用的迭代器,混合在 (inherits from)Enumerable
中。Enumerable
具有从 anEnumerable#to_a
创建 an 的方法,因此也从 an创建,因为IS-AN。Array
Enumerable
Enumerator
Enumerator
Enumerable
所以,如果你有一个Enumerator
,你需要做的就是打电话to_a
,例如
some_enum.to_a
但是,您没有Enumerator
. 你有一个方法。所以,你没有问的真正问题是问题的关键,是:我如何Enumerator
从方法创建一个?
这就是Object#enum_for
:
enum = enum_for(:foo)
#=> #<Enumerator: ...>
ary = enum.to_a
#=> [8, 2, 5]
但是请注意,在许多情况下,您实际上并不需要Array
, 因为Enumerator
继承自Enumerable
like Array
does,因此会响应许多相同的消息。
另请注意,按照惯例,Ruby 中的许多“迭代器”方法,例如Enumerable#map
,#each
等,Enumerator
在没有块的情况下调用它们时将返回 an:
def foo
return enum_for(__callee__) { 3 } unless block_given?
yield 8
yield 2
yield 5
end
然后你可以简单地做:
enum = foo
#=> #<Enumerator: ...>
ary = enum.to_a
#=> [8, 2, 5]
推荐阅读
- php - php7.4-fpm 无法启动 - 使用 nginx 在 VULTR Ubuntu 18.04 上将 PHP 7.3 更新为 PHP 7.4
- f# - NUnit 的 AreEqual 是否测试引用相等或值相等?
- phpstorm - PhpStorm 中的所有新选项卡都将打开固定
- apache-spark - 将结构列名转换为 parquet 文件中的行
- javascript - 我可以将这两个功能合并为一个吗?(以更干净的脚本的名义......)
- java - Java - JPA 可重复的@Embedded 注释
- spring - Spring - 不是托管类型:类
- swift - 在多窗口/选项卡设置中处理 EnvironmentObject
- c - 如何使结构保持通过函数分配的值?
- javascript - 使用 javascript 方法 search() 搜索关键字;