在哈希中查找键和值



我有一个哈希数组:

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.ininspect 时得到这个:

#<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

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

正如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.

给定以下哈希值(不是数组,请注意引号包装键,如所指(。

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

最新更新