【问题标题】:Extract values from nested JSON to array using JS使用 JS 从嵌套 JSON 中提取值到数组
【发布时间】:2021-05-05 07:59:27
【问题描述】:

我有一个包含嵌套对象的 JSON 文件,我需要从每个对象中提取特定键的值并保存到数组中。无需保留结构或顺序。

请参阅下面的 JSON。我需要提取 'text' 键的值并得到一个像这样的结果数组 ["CPUs", "AMD", "Ryzen", "intel",....]

实现这一目标的最佳方法是什么?

[
   {
      "itemID":"1",
      "items":[
         {
            "itemID":"2",
            "items":[
               {
                  "itemID":"3",
                  "items":[
                     {
                        "itemID":"15",
                        "text":"Ryzen"
                     },
                     {
                        "itemID":"16",
                        "text":"Threadripper"
                     }
                  ],
                  "text":"AMD",
               },
               {
                  "itemID":"66",
                  "items":[
                     {
                        "itemID":"76",
                        "text":"i5"
                     },
                     {
                        "itemID":"77",
                        "text":"i7"
                     },
                     {
                        "itemID":"78",
                        "text":"i3"
                     }
                  ],
                  "text":"Intel"
               },
               {
                  "itemID":"70",
                  "text":"Apple"
               }
            ],
            "text":"CPUs"
         }
      ],
      "text":"computer parts"
   },
   {
      "itemID":"4",
      "items":[
         {
            "itemID":"5",
            "items":[
               {
                  "itemID":"21",
                  "text":"porsche"
               },
               {
                  "itemID":"22",
                  "text":"maserati"
               },
               {
                  "itemID":"23",
                  "text":"ferrari"
               }
            ],
            "text":"sports cars"
         }
      ],
      "text":"cars"
   }
]

【问题讨论】:

    标签: javascript json javascript-objects


    【解决方案1】:

    您可以编写一个递归函数,返回当前节点的text 值,然后返回其子节点items 的所有text 值:

    const data = [{"itemID":"1","items":[{"itemID":"2","items":[{"itemID":"3","items":[{"itemID":"15","text":"Ryzen"},{"itemID":"16","text":"Threadripper"}],"text":"AMD"},{"itemID":"66","items":[{"itemID":"76","text":"i5"},{"itemID":"77","text":"i7"},{"itemID":"78","text":"i3"}],"text":"Intel"},{"itemID":"70","text":"Apple"}],"text":"CPUs"}],"text":"computer parts"},{"itemID":"4","items":[{"itemID":"5","items":[{"itemID":"21","text":"porsche"},{"itemID":"22","text":"maserati"},{"itemID":"23","text":"ferrari"}],"text":"sports cars"}],"text":"cars"}];
    
    const extract = (arr) => arr.reduce((acc, obj) => acc.concat(obj.text, extract(obj.items || [])), [])
    
    out = extract(data);
    console.log(out);

    【讨论】:

      【解决方案2】:

      简单的递归应该有助于遍历数组以获取具有text 属性的对象

      const data = [{"itemID":"1","items":[{"itemID":"2","items":[{"itemID":"3","items":[{"itemID":"15","text":"Ryzen"},{"itemID":"16","text":"Threadripper"}],"text":"AMD"},{"itemID":"66","items":[{"itemID":"76","text":"i5"},{"itemID":"77","text":"i7"},{"itemID":"78","text":"i3"}],"text":"Intel"},{"itemID":"70","text":"Apple"}],"text":"CPUs"}],"text":"computer parts"},{"itemID":"4","items":[{"itemID":"5","items":[{"itemID":"21","text":"porsche"},{"itemID":"22","text":"maserati"},{"itemID":"23","text":"ferrari"}],"text":"sports cars"}],"text":"cars"}];
      
      function getText(item) {
        let result = [];
      
        if (item.text) result.push(item.text);
        for (const key in item) {
          if (item.hasOwnProperty(key) && typeof item == 'object') result.push(...getText(item[key]));
        }
      
        return result;
      }
      
      data.forEach(item => console.log(getText(item)));

      【讨论】:

        【解决方案3】:

        这是使用object-scan 的迭代解决方案。对我来说,它比编写自定义递归函数更具可读性和可维护性。但是添加依赖显然是一种权衡

        // const objectScan = require('object-scan');
        
        const data = [{ itemID: '1', items: [{ itemID: '2', items: [{ itemID: '3', items: [{ itemID: '15', text: 'Ryzen' }, { itemID: '16', text: 'Threadripper' }], text: 'AMD' }, { itemID: '66', items: [{ itemID: '76', text: 'i5' }, { itemID: '77', text: 'i7' }, { itemID: '78', text: 'i3' }], text: 'Intel' }, { itemID: '70', text: 'Apple' }], text: 'CPUs' }], text: 'computer parts' }, { itemID: '4', items: [{ itemID: '5', items: [{ itemID: '21', text: 'porsche' }, { itemID: '22', text: 'maserati' }, { itemID: '23', text: 'ferrari' }], text: 'sports cars' }], text: 'cars' }];
        
        const find = objectScan(['**(^items$).text'], {
          useArraySelector: false,
          rtn: 'value'
        });
        
        console.log(find(data));
        /* => [
          'cars',    'sports cars',
          'ferrari', 'maserati',
          'porsche', 'computer parts',
          'CPUs',    'Apple',
          'Intel',   'i3',
          'i7',      'i5',
          'AMD',     'Threadripper',
          'Ryzen'
        ] */
        .as-console-wrapper {max-height: 100% !important; top: 0}
        <script src="https://bundle.run/object-scan@14.3.0"></script>

        免责声明:我是object-scan的作者

        【讨论】:

          猜你喜欢
          • 2019-08-25
          • 2019-07-06
          • 1970-01-01
          • 2017-12-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多