Ruby - 如何将数组添加到哈希键?

时间:2016-07-27 16:04:59

标签: ruby-on-rails arrays ruby hash

我有这个循环:

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

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

谢谢。

3 个答案:

答案 0 :(得分: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 :(得分: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对我来说似乎有点奇怪。特别是,在Hash中混合使用不同类型的信息是一种从其他非面向对象语言继承的非常糟糕的方法。

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

答案 2 :(得分: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

如果在任何情况下都存在NEW密钥,请参阅下面@tadman的评论。