在哈希中查找键和值

时间:2018-08-27 08:05:03

标签: arrays ruby hash

我有一个哈希数组:

b = [
  {
    id: 2,
    Sector: "Crops",
    2011-12: 17.6,
    2012-13: 18.9,
    2013-14: 14.2,
    2014-15: 13.1,
    2015-16: 12.3,
    2016-17: 12.1,
    created_at: "2018-08-27T06:11:29.000Z",
    updated_at: "2018-08-27T06:11:29.000Z"
  }
]

我正在从数据库中获取此数组。

我想映射键和哈希值以得到一个像这样的新数组:

[
  {
    y: 17.6,
    label: "2011-12"
  },
  {
    y:18.9,
    label: "2012-13",
    ...
  }
]

我正在尝试以下代码:

u = []
b.each do |col|
  u.push({y:25, label:"2011"})
  u.push({y:35, label:"2012"})
end

这将生成一个新数组,正如我期望的那样,但是当我尝试使用以下方法获取键和值时:

b.each do |col|
  col.each do |key, value|
    puts "The hash key is #{key} and the value is #{value}."
  end
end

我收到此错误:

undefined method `each' for

这有什么问题?我如何获取任何哈希的键和值以及如何在我的情况下使用它?

我可以看到错误是2011-12:17.6,2011-12应该是字符串。但是我正在从数据库中获得此​​值。如果要创建格式的数组,如何解决此问题。

所以我的问题是我的列名在2012-13中,当我运行查询时,我按原样获取价值。

使用b.inspect时我得到了这个信息:

 #<ActiveRecord::Relation [#<AnnualStateDomesticProduct3 id: 2, Sector: "Crops", 2011-12: 17.6, 2012-13: 18.9, 2013-14: 14.2, 2014-15: 13.1, 2015-16: 12.3, 2016-17: 12.1, created_at: "2018-08-27 06:11:29", updated_at: "2018-08-27 06:11:29">]>

我对该表的迁移是:

def change
create_table :annual_state_domestic_product3s do |t|
  t.string :Sector
  t.float :'2011-12'
  t.float :'2012-13'
  t.float :'2013-14'
  t.float :'2014-15'
  t.float :'2015-16'
  t.float :'2016-17'

  t.timestamps
end

所以我的问题是如何获取字符串格式的值?

2 个答案:

答案 0 :(得分:0)

hermanvicente所说,2011-12不是有效的哈希键(它是一个表达式)。必须用字符串引用。

b = [
  {
    id: 2,
    "Sector": "Crops",
    "2011-12": 17.6,
    "2012-13": 18.9,
    "2013-14": 14.2
  }
]

b.each do |col|
  col.each do |key, value|
    puts "The hash key is #{key} and the value is #{value}."
  end
end

打印

The hash key is id and the value is 2.
The hash key is Sector and the value is Crops.
The hash key is 2011-12 and the value is 17.6.
The hash key is 2012-13 and the value is 18.9.
The hash key is 2013-14 and the value is 14.2.

答案 1 :(得分:0)

给出以下哈希值(不是数组,请注意指出的引号括住键)。

h = {
      id: 2,
      Sector: "Crops",
      "2011-12": 17.6,
      "2012-13": 18.9,
      "2013-14": 14.2,
      "2014-15": 13.1,
      "2015-16": 12.3,
      "2016-17": 12.1,
      created_at: "2018-08-27T06:11:29.000Z",
      updated_at: "2018-08-27T06:11:29.000Z"
    }

这是获得所需结果的一种方法。

h.delete_if { |k,v| [:id, :Sector, :created_at, :updated_at].include? k }
.each_with_object([]) { |pair, ary| ary << { y: pair.last, label: pair.first } }

# => [{:y=>17.6, :label=>:"2011-12"}, {:y=>18.9, :label=>:"2012-13"}, ... ]

也许您需要更改键的数组以删除到['id', 'Sector', 'created_at', 'updated_at']

如果您有一个哈希数组(您的b变量),请使用提供的代码映射每个元素:

result = array_of_hashes.map do |h|
  h.delete_if { |k,v| [:id, :Sector, :created_at, :updated_at].include? k }
  .each_with_object([]) { |pair, ary| ary << { y: pair.last, label: pair.first } }
end

编辑-从数据库中获取正确的哈希数组

这是一种可能的解决方案,因为列名不是标准的,并且从数据库返回的对象如下所示:

#<ActiveRecord::Relation [#<AnnualStateDomesticProduct3 id: 2, Sector: "Crops", 2011-12: 17.6, 2012-13: 18.9, 2013-14: 14.2, 2014-15: 13.1, 2015-16: 12.3, 2016-17: 12.1, created_at: "2018-08-27 06:11:29", updated_at: "2018-08-27 06:11:29">]>

一种解决方法是将其转换为JSON,然后解析为哈希,正如一个注释中已经指出的那样:

b = JSON.parse(AnnualStateDomesticProduct.all.to_json)

此外,要从对象获取属性值,您可以像这样“调用列”:

a = AnnualStateDomesticProduct.find(2)
a.send('2011-12') # => 17.6