在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,这就是迭代器被称为红宝石,在(从继承)混合Enumerable。Enumerable具有从 anEnumerable#to_a创建 an的方法,因此也从 an ,因为IS-AN。ArrayEnumerableEnumeratorEnumerator 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]
但是请注意,在许多情况下,您实际上并不需要 an Array,因为就像do一样Enumerator继承自,因此会响应许多相同的消息。EnumerableArray
另外请注意,按照惯例,许多“迭代”的方法在Ruby中,例如Enumerable#map,#each等等,将返回Enumerator时,他们被称为无块:
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]