【问题标题】:How can I pull an IPv4 address from a JSON response by seacrhing nested values?如何通过搜索嵌套值从 JSON 响应中提取 IPv4 地址?
【发布时间】:2018-06-23 00:51:16
【问题描述】:

我是 Ruby 的新手,现在已经被困了一段时间了。我收到如下所述的 JSON 响应,旨在搜索其子字符串的值是我指定的值的子字符串。

例如,我收到以下响应:

{
  "00:00:00:CC:00:CC": {
    "family": "lladdr"
  },
  "10.0.0.20": {
    "family": "inet",
    "prefixlen": "24",
    "netmask": "255.255.255.0",
    "broadcast": "10.0.0.255",
    "scope": "Global"
  },
  "ff00::f00:00ff:fff0:00f0": {
    "family": "inet6",
    "prefixlen": "64",
    "scope": "Link",
    "tags": []
  }
}

我需要获取键family 的值等于inet 的父项的值。在这种情况下,我只希望 10.0.0.20 在 family 等于 inet 时作为输出。

我在这里遇到了多个问题,但 Google 没有提供帮助。我知道我需要使用 JSON.parse 解析 JSON,然后使用可能的 find 或 select 来获得我的答案,但我无法让它工作。

我不确定是否有任何其他方法可以做到这一点,就像你在 Bash 中使用 grep 或 awk 所做的那样。一种技巧可能是使用foo.[46..54] 之类的东西来输出IP,但我再次相信这是解决这个问题的不好方法。

【问题讨论】:

  • 我认为这是一个合理的问题,因为以这种方式搜索嵌套的键/值对并不简单。这个问题或许可以改进,但我认为这是一个值得提出的问题。

标签: json ruby hash ip-address ipv4


【解决方案1】:

使用哈希#invert

假设您的哈希已经使用JSON#parse 存储在response 中,解决问题的一种方法是使用Hash#invert 方法反转哈希。例如:

# Return an Array of IPv4, then pop the last/only String value.
response.invert.select { |h| h.values.include? 'inet' }.values.pop
#=> "10.0.0.20"

这既快速又简单,并且适用于您提供的数据。但是,有一些小警告。

注意事项

  1. 假设 response 哈希中只有一个 IPv4 地址。如果您有多个以inet 为值的键,请不要使用pop,并按照您认为合适的方式处理生成的数组。例如:

    response.invert.select { |h| h.values.include? 'inet' }.values
    #=> ["10.0.0.20"]
    
  2. 它假定每个顶级 JSON 对象的键是一个 IP 地址。我们并没有真正验证任何事情。

  3. 它适用于您拥有的 JSON,但不适用于任意嵌套或变化的数据结构。如果您有不同类型的输入,请将其视为“需要一些组装”。

  4. 如果您没有inet 家庭,那么{}.values.pop 可能会返回零。确保您在应用程序中对此进行了计划。

这些都不是您特定用例的阻碍,但它们当然值得牢记。您的里程可能会有所不同。

【讨论】:

    【解决方案2】:

    如果你想要family inet

    result = JSON.parse(response)
    family = result.detect { |k,v| v['family'] == 'inet' }
    family[0] # 10.0.0.20
    

    注意,detect 会返回一个数组。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 2018-05-13
      • 2014-03-29
      • 1970-01-01
      相关资源
      最近更新 更多