gpt4 book ai didi

Ruby 自定义迭代器

转载 作者:太空宇宙 更新时间:2023-11-03 17:11:13 26 4
gpt4 key购买 nike

我有一个类game其中包含一些自定义对象数组(恐龙、白鲸等),这些对象由不同的访问器返回,例如 game.dinosaurs , game.cavemen等等

目前,所有这些访问器都只返回内部存储的数组。但现在我想向这些访问器返回的这些数组添加一些自定义迭代方法,以便能够编写类似 game.dinosaurs.each_carnivore { ... } 的代码。等类似于each_elementeach_attr LibXML::XML::Node 中的迭代器.但是从我的访问器返回的对象 game.dinosaursgame.cavemen仍然必须表现得像数组。

在 Ruby 中通常如何完成类似的事情?我是否应该使访问器返回的对象成为一些派生自 Ruby 的 Array 的自定义类?类(class)?或者也许我应该用 Enumerable 创建一个自定义类混进去了?

我知道我可以使用 mapselect外部在我的收藏中,但我想在内部封装这些迭代,这样我类的用户就不需要费心如何设置迭代以仅从内部数组中选择食肉恐龙。

编辑:我不是在问如何使用迭代器或如何实现它们,而是如何将一些自定义迭代器添加到以前只是普通数组的对象(并且仍然需要).

最佳答案

这取决于(一如既往)。您可以使用数组子类,也可以构建自定义类并使用组合和委托(delegate)。这是一个带有数组子类的简单示例:

class DinosaurArray < Array
def carnivores
select { |dinosaur| dinosaur.type == :carnivore }
end

def herbivores
select { |dinosaur| dinosaur.type == :herbivore }
end

def each_carnivore(&block)
carnivores.each(&block)
end

def each_herbivore(&block)
herbivores.each(&block)
end
end

这是一个简单的组合和委托(delegate):

class DinosaurArray
def initialize
@array = []
end

def <<(dinosaur)
@array << dinosaur
end

def carnivores
@array.select { |dinosaur| dinosaur.type == :carnivore }
end

def herbivores
@array.select { |dinosaur| dinosaur.type == :herbivore }
end

def each(&block)
@array.each(&block)
end

def each_carnivore(&block)
carnivores.each(&block)
end

def each_herbivore(&block)
herbivores.each(&block)
end
end

两种实现都可以这样使用:

require 'ostruct'

dinosaurs = DinosaurArray.new
dinosaurs << OpenStruct.new(type: :carnivore, name: "Tyrannosaurus")
dinosaurs << OpenStruct.new(type: :carnivore, name: "Allosaurus")
dinosaurs << OpenStruct.new(type: :herbivore, name: "Apatosaurus")

puts "Dinosaurs:"
dinosaurs.each.with_index(1) { |dinosaur, i| puts "#{i}. #{dinosaur.name}" }
puts

但也有自定义迭代器:

puts "Carnivores:"
dinosaurs.each_carnivore.with_index(1) { |dinosaur, i| puts "#{i}. #{dinosaur.name}" }
puts

puts "Herbivores:"
dinosaurs.each_herbivore.with_index(1) { |dinosaur, i| puts "#{i}. #{dinosaur.name}" }

输出:

Dinosaurs:
1. Tyrannosaurus
2. Allosaurus
3. Apatosaurus

Carnivores:
1. Tyrannosaurus
2. Allosaurus

Herbivores:
1. Apatosaurus

关于Ruby 自定义迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18525645/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com