哈希数组推入另一个数组

时间:2018-05-25 13:54:20

标签: ruby-on-rails arrays ruby loops

我的数组中包含哈希值,我想从哈希值中过滤掉一些参数,并将过滤后的数据插入另一个数组中但下面不成功的是我使用的样本数据

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"}
]

有人请帮忙解决这个问题,提前致谢

6 个答案:

答案 0 :(得分:5)

您可以结合mapslice

获得预期结果
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

快乐编码