在 Ruby 中操作嵌套哈希数组的输出

J. *_*ard 1 ruby arrays hash

我一直在从 JSON 中的 API 中提取数据,并且目前正在遇到一个重要的问题

数据是关于公司的,比如谷歌和 Facebook,并且在一个数组或散列中,如下所示:

[
  {"id"=>"1", "properties"=>{"name"=>"Google", "stock_symbol"=>GOOG, "primary_role"=>"company"}},
  {"id"=>"2", "properties"=>{"name"=>"Facebook", "stock_symbol"=>FB, "primary_role"=>"company"}}
]
Run Code Online (Sandbox Code Playgroud)

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

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

有任何想法吗?

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

谢谢!

spi*_*eap 6

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

假设您的数据如下所示(我在GOOG和周围添加了引号FB):

data = [
  {"id"=>"1", "properties"=>{"name"=>"Google", "stock_symbol"=>"GOOG", "primary_role"=>"company"}},
  {"id"=>"2", "properties"=>{"name"=>"Facebook", "stock_symbol"=>"FB", "primary_role"=>"company"}}
]
Run Code Online (Sandbox Code Playgroud)

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

data.each do |result|
   puts result["id"]
end
Run Code Online (Sandbox Code Playgroud)

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

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

  # method 2  
  puts result.dig("properties", "name")
end
Run Code Online (Sandbox Code Playgroud)

方法 #1 使用hash[key]语法,并且因为第一个哈希值是另一个哈希值,所以可以链接它以获得您想要的结果。这种方法的缺点是,如果您properties的结果之一缺少键,您将收到错误消息。

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

从散列中删除元素

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

  1. primary_role从嵌套散列中删除键,或
  2. 创建一个包含除primary_role键之外的所有数据的新对象。

我通常会选择后者,并建议阅读不变性和不可变数据结构。

但是,要实现 [1],您可以delete对密钥进行就地操作:

data.each do |company| 
  company["properties"].delete("primary_role")
end
Run Code Online (Sandbox Code Playgroud)

将元素添加到哈希

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

data.each do |company| 
  company["properties"]["industry"] = "Advertising/Privacy Invasion"
end
Run Code Online (Sandbox Code Playgroud)

这会给你留下类似的东西:

[
  {
    "id"=>"1", 
    "properties"=>{
      "name"=>"Google", 
      "stock_symbol"=>"GOOG", 
      "industry"=>"Advertising/Privacy Invasion"
    }
  },
  {
    "id"=>"2", 
    "properties"=>{
      "name"=>"Facebook", 
      "stock_symbol"=>"FB", 
      "industry"=>"Advertising/Privacy Invasion"
    }
  }
]
Run Code Online (Sandbox Code Playgroud)