我学习红宝石。
我想知道ruby中的enumerable和iterator方法之间的区别,以及为什么我们使用枚举器方法..
对我来说两个看起来都一样。我想知道两者之间的区别
普通迭代器方法
[TestFixture]
public class TestsSample
{
[SetUp]
public void Setup() { }
[TearDown]
public void Tear() { }
[Test]
public void Pass()
{
Console.WriteLine("test1");
Assert.True(true);
}
[Test]
public void Fail()
{
Assert.False(true);
}
[Test]
[Ignore("another time")]
public void Ignore()
{
Assert.True(false);
}
[Test]
public void Inconclusive()
{
Assert.Inconclusive("Inconclusive");
}
}
每个使用枚举器
3.times do
|x| puts x
end
也适用于字符串
enumerator = 3.times
enumerator.each do
|x| puts x
end
使用枚举器对象
"scriptkiddie".each_char{|x| puts x}
使用枚举器有什么好处。我应该在哪里使用Enumerator?
请帮助我理解差异
答案 0 :(得分:5)
[1,2,3].each.is_a?(Enumerable)
#=> true
[1,2,3].each.is_a?(Enumerator)
#=> true
[1,2,3].each.class.ancestors
#=> [Enumerator, Enumerable, Object, Kernel, BasicObject]
是的,"迭代器"当没有使用块时,each
返回Enumerator
。
但是,如果你只是学习Ruby并希望迭代一个数组/范围/哈希,那就知道使用each
将涵盖大多数情况:
[1, 2, 3].each do |element|
puts element
end
# 1
# 2
# 3
('a'..'e').each do |element|
puts element
end
# a
# b
# c
# d
# e
{'a' => 1, 'b' => 2}.each do |key, value|
puts key
puts value
end
# a
# 1
# b
# 2
在您的级别上,您不必关心这些方法的定义位置,类别或模块或方式。
最后,for loops
不应该在Ruby中使用,因为它们可以显示奇怪的行为。
你提出的问题更加清楚,这很好。请注意,更改可能会被忽视,特别是如果您已经接受了答案。
3.times do |x|
puts x
end
enumerator = 3.times
enumerator.each do |x|
puts x
end
像这样使用,两者完全相同。由于第二个更详细,enumerator
可能不会在其他任何地方使用,因此没有理由使用第二个变体。无论如何enumerator
比3.times
更长:)
请注意,|x|
应与块开始位于同一行。 Rubocop可以帮到你。
"scriptkiddie".each_char{|x| puts x}
"scriptkiddie".enum_for(:each_char).each{|x| puts x}
同样,如果您只是创建一个枚举器并直接在其上调用each
,则没有理由使用第二个变体。
使用Enumerator
的一个原因是能够链接Enumerable
方法:
puts 3.times.cycle.first(7)
#=> [0, 1, 2, 0, 1, 2, 0]
或
"script".each_char.with_index{|c, i|
puts "letter #{i} : #{c}"
}
# letter 0 : s
# letter 1 : c
# letter 2 : r
# letter 3 : i
# letter 4 : p
# letter 5 : t
枚举器还可以使用无限列表。
require 'prime'
every_prime = Prime.each
p every_prime.first(20)
#=> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]
p every_prime.lazy.select{|x| x > 1000}.first(3)
#=> [1009, 1013, 1019]
可以为自定义迭代定义新的枚举器:
require 'date'
def future_working_days(start_date = Date.today)
date = start_date
Enumerator.new do |yielder|
loop do
date += 1
yielder << date unless date.saturday? || date.sunday?
end
end
end
puts future_working_days.take(3)
# 2017-02-01
# 2017-02-02
# 2017-02-03