如何根据Person对象的id属性唯一性过滤列表中的重复对象?
Ruby中按对象属性(id)对列表去重的优雅实现
需求说明
给定一个包含多个Person对象的列表,每个对象包含int类型的id属性,需要过滤列表,确保每个id在结果中仅出现一次(保留首次出现的对象)。
示例:
原列表:
Person(1), Person(1), Person(2), Person(2), Person(3), Person(1)
过滤后结果:
Person(1), Person(2), Person(3)
最优优雅实现
Ruby内置的Enumerable#uniq方法支持通过块自定义唯一性判断逻辑,这就是最优雅的解决方案:
filtered_list = person_list.uniq { |person| person.id }
代码示例验证
class Person attr_reader :id def initialize(id) @id = id end def to_s "Person(#{@id})" end end # 初始化测试列表 person_list = [ Person.new(1), Person.new(1), Person.new(2), Person.new(2), Person.new(3), Person.new(1) ] # 执行去重 filtered_list = person_list.uniq { |p| p.id } # 输出结果 puts filtered_list.join(', ') # 输出:Person(1), Person(2), Person(3)
方案优势
- 简洁性:一行代码完成需求,语义清晰,直接表达“按person的id去重”的意图。
- 性能优化:Ruby内部对
uniq方法的实现做了优化,无需手动维护集合状态,避免重复造轮子。 - 可读性:符合Ruby的“优雅简洁”设计哲学,其他开发者能快速理解代码逻辑。
对比暴力解法
手动维护集合的暴力解法虽然可行,但代码冗余且不够优雅:
require 'set' seen_ids = Set.new filtered_list = [] person_list.each do |person| unless seen_ids.include?(person.id) seen_ids.add(person.id) filtered_list << person end end
这种写法需要手动管理已出现的id集合和结果列表,代码量更大,可读性不如内置方法。
内容的提问来源于stack exchange,提问作者Kevin2566
相关产品推荐
相关产品推荐

