在这段代码中,我创建了一个字符串“1”到“10000”的数组:
array_of_strings = (1..10000).collect {|i| String(i)}
Ruby Core API是否提供了一种获取可枚举对象的方法,该对象允许我在同一列表中进行枚举,根据需要生成字符串值,而不是生成字符串数组?
这是另一个例子,希望澄清我想要做的事情:
def find_me_an_awesome_username
awesome_names = (1..1000000).xform {|i| "hacker_" + String(i) }
awesome_names.find {|n| not stackoverflow.userexists(n) }
end
xform
是我正在寻找的方法。
awesome_names是一个Enumerable,因此xform
不会创建一个100万字符串的字符串数组,而只是根据需要生成和返回“hacker_ [N]”形式的字符串。
顺便说一句,这就是C#中的样子:
var awesomeNames = from i in Range(1, 1000000) select "hacker_" + i;
var name = awesomeNames.First((n) => !stackoverflow.UserExists(n));
(一种解决方案)
以下是Enumerator的扩展,它添加了一个xform方法。它返回另一个枚举器,它迭代原始枚举器的值,并应用了一个变换。
class Enumerator
def xform(&block)
Enumerator.new do |yielder|
self.each do |val|
yielder.yield block.call(val)
end
end
end
end
# this prints out even numbers from 2 to 10:
(1..10).each.xform {|i| i*2}.each {|i| puts i}
答案 0 :(得分:6)
Ruby 2.0引入了Enumerable#lazy
,允许其链接map
,select
等等,并且只在最后使用to_a
生成最终结果,{ {1}}等等......您可以在任何带有first
的Ruby版本中使用它。
require 'backports/2.0.0/enumerable/lazy'
否则,您可以使用require 'backports/2.0.0/enumerable/lazy'
names = (1..Float::INFINITY).lazy.map{|i| "hacker_" + String(i) }
names.first # => 'hacker_1'
。它是Ruby 1.9中的新功能,所以Enumerator.new { with_a_block }
如果你需要它在Ruby 1.8.x中。
根据您的示例,以下内容不会创建中间数组,只会构造所需的字符串:
require 'backports/1.9.1/enumerator/new'
如果需要,您甚至可以将100000替换为1.0 / 0(即无穷大)。
要回答您的评论,如果您始终将您的值一对一映射,则可以使用以下内容:
require 'backports/1.9.1/enumerator/new'
def find_me_an_awesome_username
awesome_names = Enumerator.new do |y|
(1..1000000).each {|i| y.yield "hacker_" + String(i) }
end
awesome_names.find {|n| not stackoverflow.userexists(n) }
end
答案 1 :(得分:1)
听起来你想要一个Enumerator对象,但不完全是。
也就是说,Enumerator对象是一个可用于按需调用next
的对象(而不是执行整个循环的each
)。 (许多人使用内部迭代器与外部迭代器的语言:each
是内部的,而枚举器是外部的。你可以驱动它。)
以下是枚举器的外观:
awesome_names = Enumerator.new do |y|
number = 1
loop do
y.yield number
number += 1
end
end
puts awesome_names.next
puts awesome_names.next
puts awesome_names.next
puts awesome_names.next
这是一个链接,更多讨论如何在Ruby中懒惰地使用枚举器:http://www.michaelharrison.ws/weblog/?p=163
在Pickaxe的书中也有一节(Dave Thomas的 Programming Ruby )。
答案 2 :(得分:1)
class T < Range
def each
super { |i| yield String(i) }
end
end
T.new(1,3).each { |s| p s }
$ ruby rsc.rb
"1"
"2"
"3"
接下来要做的是在没有块的情况下调用时返回一个Enumerator ...
答案 3 :(得分:0)
列表包含每种方法:
(1..100000).each