【问题标题】:Get data from nested array of objects从嵌套的对象数组中获取数据
【发布时间】:2020-02-26 09:53:26
【问题描述】:

我正在尝试解析 JSON 文件以从同一文件中的字典中获取特定值和 .items[] 名称。

Source.json 文件:https://jqplay.org/s/0-o4HOox-K

{
  "name": "ABC Company",
  "assetbase": [{
    "name": "Added assets from API",
    "type": "access-section",
    "assetbase": [{
      "name": "Database A",
      "asset-number": 1,
      "items": ["0ABC-001", "0ABC-003", "0ABC-004"]
    }, {
      "name": "Database B",
      "asset-number": 2,
      "items": ["0ABC-001"]
    }, {
      "name": "Database C",
      "asset-number": 3,
      "items": ["0ABC-002", "0ABC-003"]
    }]
  }],
  "objects-dictionary": [{
    "uid": "0ABC-001",
    "name": "Cluster A"
  }, {
    "uid": "0ABC-002",
    "name": "Cluster B"

  }, {
    "uid": "0ABC-003",
    "name": "Unit-001"
  }, {
    "uid": "0ABC-004",
    "name": "Unit-002"
  }]
}

预期输出:

"Database A","Cluster A";"Unit-001";"Unit-002"
"Database B","Cluster A"
"Database C","Cluster B";"Unit-001"

我查看了类似的线程并在 jqplay 上随机测试但根本无法获得输出。

【问题讨论】:

  • 首先,请将您编写的用于解决此问题的代码添加到问题中,以便我们帮助您调试它。其次,预期的输出不是有效的数据结构。

标签: jquery arrays json bash dictionary


【解决方案1】:

jq解决方案:

jq -r '([(."objects-dictionary"[] | {key:.uid, value:.name})] | from_entries
       ) as $obj
       | .assetbase[] | .assetbase[]
       | [.name, (.items[] as $i | $obj[$i])]
       | @csv' < file.json

它只使用逗号,没有分号,但我担心 jq 做不到。

【讨论】:

  • 简洁漂亮的解决方案,谢谢楼主分享。
【解决方案2】:

这不是 bash 解决方案,而是 JS 解决方案。

下面的 sn-p 创建一个以数据库名称为键的对象(查看控制台):

const data = {
  "name": "ABC Company",
  "assetbase": [{
    "name": "Added assets from API",
    "type": "access-section",
    "assetbase": [{
      "name": "Database A",
      "asset-number": 1,
      "items": ["0ABC-001", "0ABC-003", "0ABC-004"]
    }, {
      "name": "Database B",
      "asset-number": 2,
      "items": ["0ABC-001"]
    }, {
      "name": "Database C",
      "asset-number": 3,
      "items": ["0ABC-002", "0ABC-003"]
    }]
  }],
  "objects-dictionary": [{
    "uid": "0ABC-001",
    "name": "Cluster A"
  }, {
    "uid": "0ABC-002",
    "name": "Cluster B"

  }, {
    "uid": "0ABC-003",
    "name": "Unit-001"
  }, {
    "uid": "0ABC-004",
    "name": "Unit-002"
  }]
}

const mapAssets = (assetbase, dictionary) => {
  const ret = assetbase.reduce((a, c) => {
    if (typeof a[c.name] === "undefined") a[c.name] = []
    a[c.name].push(c.name)
    c.items.forEach(e => {
      const {
        name
      } = dictionary.find(el => {
        return el.uid === e
      })
      a[c.name].push(name)
    })
    return a
  }, {})
  return ret
}

const mapped = mapAssets(data.assetbase[0].assetbase, data["objects-dictionary"])

console.log('mapped:', mapped)

【讨论】:

    【解决方案3】:

    使用jq (link),可以轻松解析.json文件。

    这里有一个非常适合您的解决方案:

    $ jq -r '.assetbase[].assetbase[] | .name' test.json |
        while read name; do echo -ne "\"$name\"," ;
          jq -r --arg name "$name" '.assetbase[].assetbase[] |
          select (.name | contains($name)) | .items[]' test.json |
          while read uid; do
            jq -r --arg uid $uid '."objects-dictionary"[] |
            select (.uid | contains($uid)) | .name' test.json |
            while read oname; do echo -ne "\"$oname\";" ; done;
          done; echo -ne "\n" ;
        done
    
    "Database A","Cluster A";"Unit-001";"Unit-002";
    "Database B","Cluster A";
    "Database C","Cluster B";"Unit-001";
    

    您可以通过常用的包管理器轻松安装它: sudo yum install -y jq 用于基于 RPM 的发行版(如 RedHat),或 sudo apt-get install -y jq 用于基于 Debian(Ubuntu 等);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-29
      • 2013-10-11
      • 1970-01-01
      • 1970-01-01
      • 2020-05-10
      • 2021-07-21
      • 1970-01-01
      相关资源
      最近更新 更多