【问题标题】:Loop through JSON array of objects and get the properties based on the matching IDs from objects循环遍历对象的 JSON 数组并根据对象的匹配 ID 获取属性
【发布时间】:2018-12-11 19:59:41
【问题描述】:

我的目标是如果 digital_assets 和 products 中的 id 匹配,则从 products 对象中获取 digital_assets 和 ProductName 的 URL 值。我能够遍历对象并获取 digital_assets 和 products 的值,但需要一些帮助才能根据 ID 比较这两个对象以获取 URL 和 ProductName 的值。以下是我到目前为止所做的。

var data = [{
        "digital_assets": [{
            "id": "AA001",
            "url": "https://via.placeholder.com/150"
        },{
            "id": "AA002",
            "url": "https://via.placeholder.com/150"
        }]
    }, {
        "products": [{
            "id": ["BB001", "AA001"],
            "ProductName": "PROD 485"
        },{
            "id": ["BB002", "AA002"],
            "ProductName": "PROD 555"
        }]
    }
];

$.each(data, function () {
    var data = this;
    //console.log(data);

    $.each(data.digital_assets, function () {
        var dAssets = this,
            id = dAssets['id'];
        // console.log(id);
    });

    $.each(data.products, function () {
        var proData = this,
            prod_id = proData['id'];
        // console.log(prod_id);

        $.each(prod_id, function () {
            var arr_id = this;
            console.log(arr_id);
        });
    });
});

我是否需要创建新数组并将值推送到新数组中?然后将这些数组 concat() 合并为一个。 ?位丢失任何帮助将不胜感激。

【问题讨论】:

  • 您可以在您的问题中添加示例结果吗?我不清楚你想要的结果是什么。
  • 使用if() 语句,您可以简单地将push() 任何匹配项放入一个新数组中。你试过吗?
  • 没有 JSON 数组这样的东西。你有一个数组。它是从 JSON 中解析出来的这一事实无关紧要,只会让您搜索答案变得更加困难。
  • @HereticMonkey 我的意思是......这样做的频率,实际上可能会使搜索答案更容易。
  • @KevinB 这将有助于查找最近的重复项,但在 JSON 滚动之前不会找到重复项;)。

标签: javascript jquery arrays json loops


【解决方案1】:

这是您可以通过Array.reduce、Array.includes、Object.entries 和Array.forEach 执行此操作的一种方法:

var data = [{ "digital_assets": [{ "id": "AA001", "url": "https://via.placeholder.com/150" }, { "id": "AA002", "url": "https://via.placeholder.com/150" } ] }, { "products": [{ "id": ["BB001", "AA001"], "ProductName": "PROD 485" }, { "id": ["BB002", "AA002"], "ProductName": "PROD 555" } ] } ]

const result = data.reduce((r,c) => { 
  Object.entries(c).forEach(([k,v]) => 
    k == 'digital_assets' 
     ? v.forEach(({id, url}) => r[id] = ({ id, url }))
     : v.forEach(x => Object.keys(r).forEach(k => x.id.includes(k) 
       ? r[k].ProductName = x.ProductName 
       : null))
  )
  return r
}, {})

console.log(Object.values(result))

【讨论】:

    【解决方案2】:

    您可以使用Array.prototype.find、Array.prototype.includes 和Array.prototype.map 非常优雅地实现这一目标。

    let data = [
       {
        "digital_assets": [
          {
            "id": "AA001",
            "url": "https://via.placeholder.com/150"
          },
          {
            "id": "AA002",
            "url": "https://via.placeholder.com/150"
          }
        ]
      },
      {
        "products": [
          {
            "id": ["BB001", "AA001"],
            "ProductName": "PROD 485"
          },
          {
            "id": ["BB002","AA002"],
            "ProductName": "PROD 555"
          }
        ]
      }
    ];
    
    // Find the 'digital_assets' array
    let assets = data.find(d => d['digital_assets'])['digital_assets'];
    
    // Find the 'products' array
    let products = data.find(d => d['products'])['products'];
    
    // Return an array of composed asset objects
    let details = assets.map(a => {
      return {
        id : a.id,
        url : a.url
        name : products.find(p => p.id.includes(a.id)).ProductName
      };
    });
    
    console.log(details);
    

    【讨论】:

      【解决方案3】:

      更改答案以满足您的需求:

      var data = [
             {
              "digital_assets": [
                {
                  "id": "AA001",
                  "url": "https://via.placeholder.com/150"
                },
                {
                  "id": "AA002",
                  "url": "https://via.placeholder.com/150"
                }
              ]
            },
            {
              "products": [
                {
                  "id": ["BB001", "AA001"],
                  "ProductName": "PROD 485"
                },
                {
                  "id": ["BB002","AA002"],
                  "ProductName": "PROD 555"
                }
              ]
            }
          ]
      let matchingIds = [];
      let data_assetsObject = data.find(element => {
          return Object.keys(element).includes("digital_assets")
      })
      let productsObject = data.find(element => {
          return Object.keys(element).includes("products")
      })
      data_assetsObject["digital_assets"].forEach(da => {
        productsObject["products"].forEach(product => {
          if (product.id.includes(da.id)){
            matchingIds.push({
              url: da.url,
              productName: product.ProductName
            })
          }
        })
      })
      console.log(matchingIds);
      

      工作小提琴:https://jsfiddle.net/z2ak1fvs/3/

      希望对您有所帮助。如果您不想使用新数组,也可以将相应的数据存储在您正在循环的元素中。

      编辑: 我想我知道为什么我被否决了。我的示例通过使数据成为对象而不是数组来工作。更改了 sn-p 以更清楚地显示这一点。 为什么 data 还是一个数组?有什么原因吗?或者您可以将其转换为对象吗?

      编辑 nr2: 更改了代码以满足期望,因为我根据您的 cmets 理解它们。它现在使用您的数据结构,无论数据是什么,您现在都可以搜索包含 digital_assets / products 属性的对象。

      干杯

      【讨论】:

      • 感谢代码。我使用原始数据结构尝试了您的代码,并将 data[0] 用于 digital_assets 和 data[1] 用于产品。我知道它的数组索引是硬编码的。有没有办法可以使用您的代码动态添加数组,因为我无法更改数据结构。
      • @Chip 的数据结构总是一样的吗?
      • 不,数据不一样。例如,如果将名为“产品类别”的新属性添加到数据中,它将生成新的对象数组,就像我们为产品所拥有的那样。当然它会影响数组索引值。
      • @Chip 再看一次。这符合您的需求吗?
      • 我会试试你编辑的代码。实际使用 API 并且无法控制数据结构。谢谢
      【解决方案4】:

      https://jsfiddle.net/2b1zutvx/

      使用地图。

       var myobj = data[0].digital_assets.map(function(x) {
          return {
              id: x.id,
              url: x.url,
              ProductName: data[1].products.filter(f => f.id.indexOf(x.id) > -1).map(m => m.ProductName)
          };
      });
      

      【讨论】:

      • 您的代码假定Digital_Assets 记录将始终是data 数组的第一个元素,而Products 将始终是第二个元素。如果在其中任何一个之前插入任何其他数据记录,这将中断。
      • @Bryan Dellinger - 感谢代码。我用 map() 试过你的代码。是否可以动态添加 data[] 而不是硬编码索引值?
      • Data.indexof 任何你想要的
      猜你喜欢
      • 2014-02-21
      • 1970-01-01
      • 2021-07-21
      • 2021-10-13
      • 2021-11-20
      • 1970-01-01
      • 2019-12-17
      • 2016-07-28
      相关资源
      最近更新 更多