2015-06-12 59 views
0

一个子集,我有车对象的数组在阵列中重复的对象,查找基于属性的红宝石

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,但是这只允许我比较整个汽车对象或单个属性。

+1

你们是不是基于某种共同属性过滤汽车的阵列,或通过汽车的阵列,以获得不同的属性的列表? –

+0

@ Francesco Pirrone - 前者 – pingu

+0

您想要:1)确定哪些车具有指定属性(例如,@engine_size = 1600','@mass = 2000'等;或2)具有相同值的组车所有的属性?请编辑您的问题以澄清,因为有些读者在评论中可能会错过您的答案。 –

回答

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

根据OP对问题的评论,你的答案似乎是唯一正确的答案。 –

0

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

1

让我们假设你已经previusly初始化汽车的数组,现在你想有一个2000cc的发动机和质量更1000Kg以上汽车的一个子集:

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

您也可以,如果使用select!你需要过滤到位。 关于docs的更多信息。

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 !