我的数组中包含哈希值,我想从哈希值中过滤掉一些参数,并将过滤后的数据插入另一个数组中但下面不成功的是我使用的样本数据
a = Array.new
a = [
{"name"=>"hello", "age"=>"12", "sex"=> "M", "city"=>"Chennai"},
{"name"=>"name2", "age"=>"26", "sex"=> "M", "city"=>"Banglore"}
]
line_item = Array.new
hash_data = {}
a.each do |datas|
hash_data[:name] = datas["name"]
hash_data[:age] = datas["age"]
line_item << hash_data
end
我得到了这个结果:
[
{:name=>"name2", :age=>"26"},
{:name=>"name2", :age=>"26"}
]
但我期待着这一点:
[
{:name=>"hello", :age=>"12"},
{:name=>"name2", :age=>"26"}
]
有人请帮忙解决这个问题,提前致谢
答案 0 :(得分:5)
a = [
{"name"=>"hello", "age"=>"12", "sex"=> "M", "city"=>"Chennai"},
{"name"=>"name2", "age"=>"26", "sex"=> "M", "city"=>"Banglore"}
]
a.map{ |e| e.slice("name", "age") }
#=> [{"name"=>"hello", "age"=>"12"}, {"name"=>"name2", "age"=>"26"}]
map
:返回包含块Array
slice
:返回Hash
,仅包含指定的键答案 1 :(得分:5)
在循环外定义散列意味着您继续添加相同的散列对象(同时覆盖其先前的值)。相反,在循环中创建一个新的哈希:
line_items = []
a.each do |datas|
hash_data = {}
hash_data[:name] = datas["name"]
hash_data[:age] = datas["age"]
line_items << hash_data
end
代码看起来有点不合时宜。让我们重构它。
我们可以在散列字面值中设置键:
line_items = []
a.each do |datas|
hash_data = { name: datas["name"], age: datas["age"] }
line_items << hash_data
end
我们可以摆脱hash_data
变量:
line_items = []
a.each do |datas|
line_items << { name: datas["name"], age: datas["age"] }
end
我们可以使用map
直接转换数组:
line_items = a.map { |h| { name: h["name"], age: h["age"] } }
#=> [{:name=>"hello", :age=>"12"}, {:name=>"name2", :age=>"26"}]
答案 2 :(得分:2)
在你的循环中,你基本上用line_item
填充hash_data
两次。然而,这是同一个目标。您可以使用.dup
补救此问题。
a.each do |datas|
hash_data[:name]=datas["name"]
hash_data[:age]=datas["age"]
line_item << hash_data.dup # <- here
end
irb(main):044:0> line_item
=> [{:name=>"hello", :age=>"12"}, {:name=>"name2", :age=>"26"}]
编辑:我更喜欢rado建议使用hash_data
在循环内移动.dup
的定义。它解决的问题不仅仅是治疗症状。
答案 3 :(得分:2)
我认为很多人都过于复杂化了。
您可以使用以下方法实现此目的:
a.map { |hash| hash.select { |key, _value| key == 'name' || key == 'age' } }
如果你想返回一个数组,你应该几乎总是使用map
,而select
只需选择符合条件的键 - 值对。
如果您设置了符号作为键,则可以在结果上调用symbolize_keys
。
我将扩展代码,使其更具可读性,但上面的一个代码可以完美运行:
a.map do |hash|
hash.select do |key, _value|
key == 'name' || key == 'age'
end
end
答案 4 :(得分:1)
在第一行hash_data[:name]=datas["name"]
上设置哈希的键。这就是为什么当循环再次迭代时,它会覆盖该值,然后将新结果推送到散列。
重用此代码的一个解决方案就是将hash_data = {}
放在循环的第一行。这样,您将在每次迭代时使用全新的哈希值。
另外,我建议您阅读有关Hash模块的文档。你会在那里找到更多有用的方法。
答案 5 :(得分:1)
如果您想要所有按键,可以执行此操作
array = [{"name"=>"hello", "age"=>"12", "sex"=> "M", "city"=>"Chennai"}, {"name"=>"name2", "age"=>"26""sex"=> "M", "city"=>"Banglore"}]
new_array = array.map{|b| b.inject({}){|array_obj,(k,v)| array_obj[k.to_sym] = v; array_obj}}
参考:inject
快乐编码