我几天前问了同样的问题,不知怎的沟通没有发生。我已经重新构建了我的问题,希望我们能够解决我需要解决的问题。
问题基本上是这样的:你如何创建一个不仅仅使用另一个可枚举的可枚举类?作为我需要做的简化但完全有效的例子,请考虑这个类:
class MyClass
include Enumerable
def get_next
return_val = rand.to_s
if return_val.match(/33/)
return nil
else
return return_val
end
end
def each
# ??????
end
end
在此课程中,get_next计算随机值。然后,如果该值彼此相邻有两个3,则该方法返回nil。否则返回值。所以你可以反复运行get_next,通常少于十次:
myob = MyClass.new
while not myob.get_next.nil?
puts 'got one'
end
实际上,get_next会搜索数千个数据点。当它找到下一个项目时,它会返回一个相当庞大的对象。 MyClass对象不可能将所有项目都插入到数组中。它需要一次只能获得一个。
事实上,我的班级在上面的结构上工作得很好。但是,我想以一种红宝石的方式实现这一点。
所以,考虑到上面的工人阶级,填写空白。每个()中有什么可以使它成为一个可枚举的类?
答案 0 :(得分:2)
填空。每个()中有什么可以使它成为一个可枚举的类?
该文件说"The class must provide a method each
, which yields successive members of the collection."。所以你可以这样做,只要他们不是nil
就继续产生价值。
def each
while val = get_next
yield val
end
end
演示:
irb(main):002:0> MyClass.new.each { |e| puts e }
0.9368650618038962
0.9784286059513836
0.9881624526762572
另一个演示(显示来自Enumerable
的方法):
irb(main):003:0> MyClass.new.map(&:to_f)
=> [0.6368065208805999, 0.6926393662295052, 0.9911564544581742, 0.35788099831068787]
这样就足以让它成为可以在Enumerable
中成功混合的意义上的(") Ruby的定义" enumerable")。从您的问题中不清楚您是否真的需要它,顺便说一句。如果您想要的是使用each
查看值,那么您甚至不需要包含Enumerable
。所做的就是为您提供其他方法,例如map
和select
。即使是for
循环也可以归功于each
,而不包括Enumerable
:
irb(main):002:0> for e in MyClass.new
irb(main):003:1> puts e
irb(main):004:1> end
0.7638166357043203
0.18409214000273166
0.39757329498164495
0.14658393540113002
0.948396753859117
0.3157122887487579
0.4804571082701993
(但请注意,for
循环通常不鼓励:[1],[2]。我只是为了进一步证明each
和Enumerable
的重要性基本迭代的 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Hi All");
PrintWriter out =response.getWriter();
out.println("<h2>Please complete our Customer Survey</h2>");
}
}
不重要。)
答案 1 :(得分:0)
class MyClass
include Enumerable
def enum
@enum ||= Enumerator.new do |y|
loop do
value = get_next
raise StopIteration.new("nil") if value.nil?
y << value
end
end
end
def each
return enum_for(:each) unless block_given?
enum.each(&Proc.new)
end
def get_next
return_val = rand.to_s
return_val.match(/33/) ? nil : return_val
end
end
mc = MyClass.new
mc.each { |e| puts e }
#⇒ 0.9354594959902887
# 0.6425492923024724
# 0.24551401459676037
# 0.17117672854168786
# 0.15611540754420283
# 0.3914491388594509
# 0.40243662946930725
# 0.3792875585148314
# 0.11978219941961588
# 0.49891129730441874