【问题标题】:How to merge nested arrays on parent id如何合并父ID上的嵌套数组
【发布时间】:2019-08-09 20:28:55
【问题描述】:

我正在尝试合并具有重复标头信息的二维数组。

在下面的示例中,它将项目 three 与项目 onetwo 合并到数组中,并将项目 five 与项目 four 合并。

示例数据

let data = [{
  header: {
    id: 1
  }, 
  items: [{
    item: 'one'
  }, {
    item: 'two'
  }]
}, {
  header: {
    id: 1
  }, 
  items: [{
    item: 'three'
  }]
}, {
  header: {
    id: 2
  }, 
  items: [{
    item: 'four'
  }]
}, {
  header: {
    id: 2
  }, 
  items: [{
    item: 'five'
  }]
}]

let i, j, l = data.length;
for (i = 0; i < l; i++) {
  let m = data[i]['items'].length;
  for (j = 0; j < m; j++) {
    if (data[i]['header']['id'] === data[i + 1]['header']['id']) {
      // merge records
    }
  }
}

我不确定如何在 if 块中进行适当的比较,因为 i + 1 最终会比 data[i]['items'].length 更长,并且在尝试合并时会看到类似的问题。

预期输出

let data = [{
  header: {
    id: 1
  }, 
  items: [{
    item: 'one'
  }, {
    item: 'two'
  }, {
    item: 'three'
  }]
}, {
  header: {
    id: 2
  }, 
  items: [{
    item: 'four'
  }, {
    item: 'five'
  }]
}]

在这里您可以看到预期的输出在id 上合并在一起1,2,34,5

如何根据标头 id 将所有类似的项目合并在一起?

【问题讨论】:

    标签: javascript arrays merge


    【解决方案1】:

    一种方法是创建一个中间对象来跟踪从输入数组中遇到了哪些标头,其值是为该标头找到的项目。创建地图后,您可以将其转换为数组:

    let data = [...];
    let mergeMap = {};
    
    data.forEach(entry => {
        mergeMap[entry.header.id] = [
            ...(mergeMap[entry.header.id] || []),
            ...entry.items
        ]
    });
    
    const merged = Object.keys(mergeMap).map(header => ({
        header,
        items: mergeMap[key]
    }))
    

    【讨论】:

    • key header.id?
    • 是的,关键是 header.id。
    • 不错!好的,我得再深入一点。我收到[header: [object Object], items: undefined]
    • 看起来header 的数据没有保留在mergeMap 中。
    • 所以,头部对象稍微复杂一些,比如{header: {id: 1, data: { obj_data }}。有没有办法使用这种方法来保留对象结构,所以它不会计算到[object Object]
    【解决方案2】:

    可以通过 Set 和 Map 调用来做到这一点。

    我们使用 Set 创建一个只有唯一 header ids 的数组

        const merged = [...new Set(data.map(({ header: { id }}) => id))]
    

    此时我们有一个具有唯一标头 ID 的数组。 [1,2] 基于样本数据。

    现在我们可以通过这个数组调用map 并从我们的原始数组中提取数据。

    const data = [{
      header: {
        id: 1
      },
      items: [{
        item: 'one'
      }, {
        item: 'two'
      }]
    }, {
      header: {
        id: 1
      },
      items: [{
        item: 'three'
      }]
    }, {
      header: {
        id: 2
      },
      items: [{
        item: 'four'
      }]
    }, {
      header: {
        id: 2
      },
      items: [{
        item: 'five'
      }]
    }];
    
    // The set gives us unique headers. And then we can map data.
    const merged = [...new Set(data.map(({ header: { id }}) => id))]
                    .map(id => ({
                      header: {
                        id
                      },
                      items: data.filter(({
                          header: {
                            id: i
                          }
                        }) => i === id)
                        .flatMap(({
                          items: i
                        }) => i)
                    }));
    
    console.log(merged);

    【讨论】:

      猜你喜欢
      • 2022-12-09
      • 2021-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多