2016-07-27 56 views
0

我有这样的循环:Ruby - 如何将数组添加到散列键?

car_data = Hash.new 
Car.all.each do |c| 
    car_data[c.brand] = c.id 
    car_data['NEW'] << c.id if c.new == 1 
end 

我有这个剪断,并试图所有新车保存到car_data['NEW'],但是这个代码保持在散列只有一个项目(应该有8)。

我也试图定义car_data['NEW']为数组:

car_data = Hash.new 
car_data['NEW'] = Hash.new 
Car.all.each do |c| 
    car_data[c.brand] = c.id 
    car_data['NEW'] << c.id if c.new == 1 
end 

但结果是一样的 - 只是一个项目。 如何将整个数组保存到散列键元素?

谢谢。

+1

Ruby约定是使用'{}'作为新的哈希,只有在提供像'Hash.new(0)'这样的默认值时才需要调用'Hash.new'。少即是多。 – tadman

回答

2

car_data['NEW']都将被声明为Array

car_data = Hash.new 
car_data['NEW'] = [] 
Car.all.each do |c| 
    car_data[c.brand] = c.id 
    car_data['NEW'] << c.id if c.new == 1 
end 

你也可以做一个单一的步骤

car_data = { new: [] } 
Car.all.each do |c| 
    car_data[c.brand] = c.id 
    car_data[:new] << c.id if c.new == 1 
end 

坦率地说,这似乎有些奇怪我一点点地以这种方式使用的哈希值。特别是,在Hash中混入不同类型的信息是从其他非面向对象语言继承的非常糟糕的方法。

我会使用至少两个单独的变量。但我对上下文的了解不足以提供有意义的例子。

3

你写道,你试图定义(初始化)car_data['NEW']作为一个数组,但你所做的是......将它初始化为一个散列。

变化:

car_data['NEW'] = Hash.new 

要:

car_data['NEW'] = [] 

完整的代码如下所示:

car_data = Hash.new 
car_data['NEW'] = [] 
Car.all.each do |c| 
    car_data[c.brand] = c.id 
    car_data['NEW'] << c.id if c.new == 1 
end 
+1

更好:'car_data = {'NEW'=> []}'。完成一次完成。 – tadman

1
car_data = Car.all.each_with_object(Hash.new { |h, k| h[k] = [] }) do |c, memo| 
    memo[c.brand] = c.id 
    memo['NEW'] << c.id if c.new == 1 
end 

,或者更简单,让我们创建它在运行中如果需要的话:

car_data = Car.all.each_with_object({}) do |c, memo| 
    memo[c.brand] = c.id 
    (memo['NEW'] ||= []) << c.id if c.new == 1 
end 

请同时参阅由下面@tadman,评论如果NEW关键是在任何情况下要存在的。

+0

可能比'{'NEW'=> []}更好,它可以选择初始化它。 – tadman

+0

@tadman这个cruft包含了一个关于如何处理“可能为零”对象的暗示。对于复杂的初始化,总是存在变体1。 – mudasobwa

+0

我知道你在说什么,但是这里的区别在于可能不初始化'NEW'键,这在默认情况下似乎是无害的。 – tadman