鉴于我有自定义类arr
的{{3}} My_class
个实例。这个类有几个不同的实例变量。我们称它们为:name
(一个字符串),:is_processed
(一个布尔值)和:date
(一个array)。所有这些都是可读的。
检查的最佳方法是什么,My_class
(称之为newbe
)的另一个给定实例是否已基于上述实例变量的内容在数组中?
使用arr.include?(newbe)
将无效,因为这会比较对象ID,不是吗?
我可以覆盖Array#include?
比较两个对象的方式吗?
在代码中说话
class My_class
attr_reader :name, :is_processed, :date
def initialize(_name, _proc, _d)
@name = _name
@is_processed = _proc
@date = _d
end
end
其他地方
first = My_class.new("First", false, DateTime.new(2001,2,3,4,5,6))
second = My_class.new("Second", true, DateTime.new(2001,2,3,4,5,6))
third = My_class.new("Third", false, DateTime.new(2001,2,3,3,2,1))
newbe = My_class.new("Second", true, DateTime.new(2001,2,3,4,5,6))
arr = [first, second, third]
arr.include?(newbe) # => false but should be true
答案 0 :(得分:3)
您希望比较某个类的实例,因此请添加comparable
,定义<=>
方法,并将这些方法添加到类实例中:
&lt;,&lt; =,==,&gt;,&gt; =,介于两者之间? (#include?使用#==)。
require 'date'
class My_class
include Comparable
attr_reader :name, :is_processed, :date
def initialize(_name, _proc, _d)
@name = _name
@is_processed = _proc
@date = _d
end
def <=>(other)
[self.name, self.is_processed, self.date]<=>[other.name, other.is_processed, other.date]
end
end
first = My_class.new("First", false, DateTime.new(2001,2,3,4,5,6))
second = My_class.new("Second", true, DateTime.new(2001,2,3,4,5,6))
third = My_class.new("Third", false, DateTime.new(2001,2,3,3,2,1))
newbe = My_class.new("Second", true, DateTime.new(2001,2,3,4,5,6))
arr = [first, second, third]
p arr.include?(newbe) # => true
#you could do arr.sort, but they are sorted allready by accident...
答案 1 :(得分:2)
将any?
与块一起使用。
my_arr.any? { |o| o.kind_of?(MyClass) }
如果您想要匹配的对象,您还可以使用detect
或find
。这些都是Enumerable
上的标准方法,大多数集合类都混合在一起。
答案 2 :(得分:2)
您应该考虑为自定义类重新定义==是否有意义,如下所示:
class My_class
def ==(other)
(other.is_a? My_class) &&
(other.name == @name) &&
(other.is_processed == @is_processed) &&
(other.date == @date)
end
end
如果你这样做,Array #include?会以你想要的方式工作。