Ruby中Array#union方法异常:元素超8个时去重失效
问题原因与解决方案
这不是Ruby的Bug,是你遗漏了关键方法的实现——必须同时重写hash和eql?方法,才能让自定义类对象在集合操作中正确工作。
为什么元素数量超过8个会失效?
Ruby的数组集合操作(比如union/|)在元素数量较少时,会直接遍历数组用eql?比较;当元素数量超过8个时,会自动切换为哈希表来优化性能,这时候就需要依赖对象的hash方法:只有当两个对象的hash值相等,且eql?返回true时,才会被视为相同元素。你只实现了eql?,没重写hash,导致不同对象的哈希值不同,哈希表无法识别它们是重复元素。
修复代码
修改类A,添加hash方法,基于name的哈希值实现:
class A attr_accessor :name def initialize(name) self.name = name end def eql?(other) other.name.eql?(name) end def hash name.hash end end
验证效果
修改后再执行as | bs,无论元素数量多少,都会正确去重,返回只包含每个name对应一个对象的数组。
内容的提问来源于stack exchange,提问作者Lars Schirrmeister
相关产品推荐
相关产品推荐

