根据Ruby中的属性子集在数组中查找重复对象

时间:2015-06-12 13:56:58

标签: arrays ruby duplicates

我有一系列汽车对象,

class Car

  def initialize(engine_size, maximum_speed, acceleration, mass)
    @engine_size = engine_size
    @maximum_speed = maximum_speed
    @acceleration = acceleration
    @mass = mass
  end

end

我希望通过比较其属性的子集来列出相同的汽车,例如:engine_size,加速度和质量。

我尝试过使用group_by,但这只允许我比较整个汽车对象或单个属性。

4 个答案:

答案 0 :(得分:2)

cars.group_by{|car| [car.engine_size, car.accelaration, car.mass]}

答案 1 :(得分:1)

让我们假设您已经普遍初始化了一系列汽车,现在您想要一个拥有2000cc发动机和超过1000千克质量的汽车子集:

result = cars.select{|car| car.engine==2000 and car.mass > 1000}

如果您需要进行过滤,也可以使用select!。 有关docs的更多信息。

答案 2 :(得分:1)

这允许您按不同的搜索属性过滤汽车:

class Car

  attr_reader :engine_size, :maximum_speed, :acceleration, :mass

  def self.cars_by_attrs(cars, args = {})

    return [] if cars.empty?

    # Checking if all the arguments in args are valid
    # instance variables on all the cars.
    all_instance_vars = cars.all? do |car|
      args.all? do |key, val|
        car.instance_variables.include? "@#{key.to_s}".to_sym
      end
    end

    unless all_instance_vars
      raise ArgumentError.new('Instance variable not found.')
    end

    cars.select do |car|
      args.all? do |key, val|
        # Checking if the instance variables can be retrieved.
        unless car.respond_to?(key)
          raise ArgumentError.new('Instance variable not accessible.') 
        end
        car.send(key) == val
      end
    end
  end

  def initialize(engine_size, maximum_speed, acceleration, mass)
    @engine_size = engine_size
    @maximum_speed = maximum_speed
    @acceleration = acceleration
    @mass = mass
    @test = true
  end


end

cars = []
cars << Car.new(10, 20, 5, 6)
cars << Car.new(10, 20, 7, 8)
cars << Car.new(12, 21, 9, 10)
puts Car.cars_by_attrs(cars, engine_size: 10, maximum_speed: 20)
# First two cars.
puts Car.cars_by_attrs(cars, mass: 10)
# 3rd car.
# puts Car.cars_by_attrs(cars, new: 10)
# Error !
# puts Car.cars_by_attrs(cars, test: 10)
# Error !

答案 3 :(得分:0)

如果你查找docs on group_by,你会发现你可以给它一个阻止。如果您使块返回您感兴趣的属性子集,那么应该为您提供所需的结果。