arrays - 有没有办法指定如何在 Ruby 2.6.0 中比较 .difference 函数的对象数组?
问题描述
我正在尝试比较一组外部定义的对象。我希望我能够做一个简单.difference
的 Ruby 2.6.0 中引入的函数,但在查看它之后:https ://ruby-doc.org/core-2.6/Array.html#method-i-差异我不确定我是否可以指定自定义比较。
好的,假设我们有一个简单的 Object Num
# Pretend we don't have access to this, just for reference
class Num
def initialize(val)
@val = val
end
def val
@val
end
end
我有两个数组,一个是另一个的子集。我想找出子集缺少的东西。在以下示例中,我希望差异是值为 3 的对象,因为它不存在于子集中。
all = [Num.new(1), Num.new(2), Num.new(3)]
subset = [Num.new(1), Num.new(2)]
默认.difference
函数比较.eql?
两个对象之间的使用,因此差异不会给出预期的结果:
all.difference(subset)
=> [#<Num:0x00007fcae19e9540 @val=1>, #<Num:0x00007fcae19e9518 @val=2>, #<Num:0x00007fcae19e94f0 @val=3>]
我能够创建自己的自定义 hacky 解决方案,以正确地为我提供我想要的值:
def custom_difference(all, subset)
diff = all.reject { |all_curr|
subset.find{ |subset_curr|
subset_curr.val == all_curr.val
} != nil
}
end
custom_difference(all, subset)
=> [#<Num:0x00007fcae19e94f0 @val=3>]
但是我想知道是否有任何方法可以利用现有.difference
功能,我也试图像这样使用以覆盖两个对象的比较方式:
all.difference(subset) { |a, b|
a.val <=> b.val
}
=> [#<Num:0x00007fcae19e9540 @val=1>, #<Num:0x00007fcae19e9518 @val=2>, #<Num:0x00007fcae19e94f0 @val=3>]
但这对调整比较发生的方式没有任何作用(AFAIK)我做错了吗?这是不可能的吗?:'(
解决方案
如果您不想像eql?
Aleksei Matiushkin 所描述的那样添加到类中(例如,如果您想对不同的事物使用多个标准),则无法重用#difference
. 做你正在做的事情几乎是你需要做的,虽然Array#include?
是 O(N^2),所以我喜欢坚持Set
:
Set.new(subset.map(&:val)).then { |s| all.reject { |x| s === x.val } }
# => [#<Num:0x00007febd32330e0 @val=3>]
或者,作为一种新方法:
module ArrayWithDifferenceBy
refine Array do
def difference_by(other)
other_set = Set.new(other.map { |x| yield x })
self.reject { |x| other_set.include?(yield x) }
end
end
end
module TestThis
using ArrayWithDifferenceBy
all = [Num.new(1), Num.new(2), Num.new(3)]
subset = [Num.new(1), Num.new(2)]
all.difference_by(subset, &:val)
end
# => [#<Num:0x00007febd32330e0 @val=3>]
推荐阅读
- java - 如何使用 JUnit 和 Mockito 返回用于单元测试的数组?
- html - Angular 9 - 父级中的多个子级
- java - java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter的解决方法
- redirect - 将 Apache .conf 用于 www 到非 www 重定向
- python - 动态模块的扩展导入系统
- apache-kafka - Kafkacat 从带有标题的文件中生成消息
- ios - 批量导入包含关系的Core Data中的大集合
- assembly - 整数到十进制的 64 位数字的字符串
- java - Hibernate:java.sql.SQLIntegrityConstraintViolationException:无法添加或更新子行:外键约束失败
- sql-server - Azure - 如何在选择语句中从外部数据源执行 UDF