【问题标题】:Remove duplicates from an array of objects but concatenate duplicate key从对象数组中删除重复项但连接重复键
【发布时间】:2021-12-23 05:28:54
【问题描述】:

我有一个看起来像这样的对象数组(示例)-

let arrTable = [
{ tableName: "name 1", tableDesc:"desc 1", tableFooter:"footer 1"},
{ tableName: "name 2", tableDesc:"desc 2", tableFooter:"footer 2"},
{ tableName: "name 1", tableDesc:"desc 1", tableFooter:"footer 3"},
{ tableName: "name 3", tableDesc:"desc 3", tableFooter:"footer 4"},
{ tableName: "name 4", tableDesc:"desc 4", tableFooter:"footer 5"},
{ tableName: "name 5", tableDesc:"desc 5", tableFooter:"footer 6"},
{ tableName: "name 6", tableDesc:"desc 6", tableFooter:"footer 7"},
];

我想删除具有相同 tableName 的重复项,但将 tableFooter 连接到不会删除的那些重复项中。

例如,预期的对象数组应该是 -

    let newTable = [
    { tableName: "name 1", tableDesc:"desc 1", tableFooter:"footer 1 footer 3"},
    { tableName: "name 2", tableDesc:"desc 2", tableFooter:"footer 2"},
    { tableName: "name 3", tableDesc:"desc 3", tableFooter:"footer 4"},
    { tableName: "name 4", tableDesc:"desc 4", tableFooter:"footer 5"},
    { tableName: "name 5", tableDesc:"desc 5", tableFooter:"footer 6"},
    { tableName: "name 6", tableDesc:"desc 6", tableFooter:"footer 7"},
    ];

我已经检查了有关如何删除重复项的其他问题,但是否有更简单的方法来连接键,而无需运行 for 循环并检查相同的 tableName 并创建一个将 tableFooter 保存在一个中的新键?

【问题讨论】:

    标签: javascript arrays sorting


    【解决方案1】:

    我建议使用Array.reduce() 来获得所需的输出。

    我们为每个 tableName 创建一个具有属性的对象,如果它已经存在,我们附加 tableFooter 值。

    let arrTable = [
    { tableName: "name 1", tableDesc:"desc 1", tableFooter:"footer 1"},
    { tableName: "name 2", tableDesc:"desc 2", tableFooter:"footer 2"},
    { tableName: "name 1", tableDesc:"desc 1", tableFooter:"footer 3"},
    { tableName: "name 3", tableDesc:"desc 3", tableFooter:"footer 4"},
    { tableName: "name 4", tableDesc:"desc 4", tableFooter:"footer 5"},
    { tableName: "name 5", tableDesc:"desc 5", tableFooter:"footer 6"},
    { tableName: "name 6", tableDesc:"desc 6", tableFooter:"footer 7"},
    ];
    
    let newTable = Object.values(arrTable.reduce((acc, { tableName, tableFooter, ...rest}) => { 
        if (!acc[tableName]) {
            acc[tableName] = { tableName, ...rest, tableFooter};
        } else {
            acc[tableName].tableFooter += ` ${tableFooter}`;
        }
        return acc;
    }, {}))
    
    console.log(newTable)
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

    • 记住 .reduce() 是 O(n^2)。
    • 我不确定在这种情况下是否准确,我们正在遍历 arrTable 数组一次,因此这将是 O(n)。
    • 这个案例看起来不错,我只是提到最坏的情况。虽然很好记^^
    • 啊,确实是的,如果我们在循环中插入一个 Array.find() 就可以了 O(n^2)。
    • 非常感谢!效果很好!
    【解决方案2】:

    您需要另一个数组,您可以在其中推送非重复项,同时修改重复项。

    这似乎有效:

    let arrTable = [
      { tableName: "name 1", tableDesc:"desc 1", tableFooter:"footer 1"},
      { tableName: "name 2", tableDesc:"desc 2", tableFooter:"footer 2"},
      { tableName: "name 1", tableDesc:"desc 1", tableFooter:"footer 3"},
      { tableName: "name 3", tableDesc:"desc 3", tableFooter:"footer 4"},
      { tableName: "name 4", tableDesc:"desc 4", tableFooter:"footer 5"},
      { tableName: "name 5", tableDesc:"desc 5", tableFooter:"footer 6"},
      { tableName: "name 6", tableDesc:"desc 6", tableFooter:"footer 7"},
    ];
    
    
    let result = [];
    
    arrTable.forEach((entry) => {
      // if the entry already exists, we just update its footer...
      // if you still need the original, make sure to make a copy of the entry here
      let existingEntry = result.find((e) => entry.tableName === e.tableName);
      if (existingEntry) {
        existingEntry.tableFooter += entry.tableFooter;
      } else {
        // new entries are added as they are
        result.push(entry);
      }
    });
    
    console.log('RESULT', result);
    

    【讨论】:

    • 非常感谢!!
    猜你喜欢
    • 2017-04-10
    • 2019-02-28
    • 1970-01-01
    • 1970-01-01
    • 2016-03-12
    相关资源
    最近更新 更多