在Ruby中处理嵌套哈希数组的输出

时间:2018-05-25 12:35:55

标签: arrays ruby hash

我一直在从JSON中的API中提取数据,目前我正在解决一个小问题

数据来自Google和Facebook等公司,并且是数组或哈希,如下所示:

[
  {"id"=>"1", "properties"=>{"name"=>"Google", "stock_symbol"=>GOOG, "primary_role"=>"company"}},
  {"id"=>"2", "properties"=>{"name"=>"Facebook", "stock_symbol"=>FB, "primary_role"=>"company"}}
]

以下是我想尝试的两项操作:

  1. 对于每家公司,打印出名称,ID和股票代码(即“Google - 1 - GOOG”和“Facebook - 2 - FB”)
  2. 从Google和Facebook中删除“主要角色”键/值
  3. 为Google和Facebook分配新的“行业”键/值
  4. 有什么想法吗?

    我是Ruby的初学者,但遇到了一些数组和哈希的函数/方法(例如未定义的方法)的问题,因为这看起来像是一个哈希数组

    谢谢!

1 个答案:

答案 0 :(得分:4)

Ruby提供了一些工具来帮助我们理解数组,哈希和两者的嵌套混合。

假设您的数据是这样的(我在GOOGFB附近添加了引号):

data = [
  {"id"=>"1", "properties"=>{"name"=>"Google", "stock_symbol"=>"GOOG", "primary_role"=>"company"}},
  {"id"=>"2", "properties"=>{"name"=>"Facebook", "stock_symbol"=>"FB", "primary_role"=>"company"}}
]

您可以使用each迭代数组,例如:

data.each do |result|
   puts result["id"]
end

挖掘哈希并打印结果可以通过以下几种方式完成:

data.each do |result|
  # method 1
  puts result["properties"]["name"]

  # method 2  
  puts result.dig("properties", "name")
end

方法#1使用hash[key]语法,并且因为第一个哈希值是另一个哈希值,所以它可以链接以获得您所追求的结果。这种方法的缺点是,如果您的某个结果中缺少properties密钥,则会出现错误。

方法#2使用dig,它接受​​嵌套键作为参数(按顺序)。它将深入挖掘嵌套的哈希值并提取值,但如果缺少任何步骤,它将返回nil,如果您正在处理来自外部源的数据,这可能会更安全一些

从哈希

中删除元素

你的第二个问题涉及更多。你有两个选择:

  1. 从嵌套哈希中删除primary_role个键,或
  2. 创建一个新对象,其中包含除primary_role键以外的所有数据。
  3. 我通常会选择后者,并建议阅读不变性和不可变数据结构。

    但是,要实现[1],您可以执行密钥的就地delete

    data.each do |company| 
      company["properties"].delete("primary_role")
    end
    

    将元素添加到哈希

    您只需使用hash[key] = value分配新的哈希值,因此您可以使用以下内容设置行业:

    data.each do |company| 
      company["properties"]["industry"] = "Advertising/Privacy Invasion"
    end
    

    会给你留下类似的东西:

    [
      {
        "id"=>"1", 
        "properties"=>{
          "name"=>"Google", 
          "stock_symbol"=>"GOOG", 
          "industry"=>"Advertising/Privacy Invasion"
        }
      },
      {
        "id"=>"2", 
        "properties"=>{
          "name"=>"Facebook", 
          "stock_symbol"=>"FB", 
          "industry"=>"Advertising/Privacy Invasion"
        }
      }
    ]