【问题标题】:Merge objects based on same key from different positions in an array基于数组中不同位置的相同键合并对象
【发布时间】:2023-04-22 15:44:01
【问题描述】:

我有 2 个包含 20 个对象的数组,我想按名称合并它们。每个数组中名称的顺序不同,顺序很重要,必须保持原样。这使我无法使用传统的排序和for 循环方法。基本上,我所拥有的是:

var tempList1 = [
   {'manager':'John', 'x1':0, 'y1':0, 'x2':1, 'y2':1},
   {'manager':'Tom', 'x1':0, 'y1':50, 'x2':1, 'y2':1},
   {'manager':'Julie', 'x1':0, 'y1':80, 'x2':1, 'y2':1},
...
];

var tempList2 = [
   {'manager':'Tom', 'x3':0, 'y3':10, 'x4':1, 'y4':1},
   {'manager':'Julie', 'x3':0, 'y3':90, 'x4':1, 'y4':1},
   {'manager':'John', 'x3':0, 'y3':50, 'x4':1, 'y4':1},
...
];

请注意,John 位于 tempList1 中的索引 0 处,但位于 tempList2 处的索引 2 处。当我尝试时:

          for (var k = 0; k < managerList.length; k++) {
            let merged = {...tempList1[k],...tempList2[k]}
            combinedList.push(merged);
          }

我错误地假设每个数组中的顺序是相同的——实际上不是。

最终结果应该是:

var combinedList = [
    {'manager':'John', 'x1':0, 'y1':0, 'x2':1, 'y2':1, 'x3':0, 'y3':50, 'x4':1, 'y4':1},
    {'manager':'Tom', 'x1':0, 'y1':50, 'x2':1, 'y2':1, 'x3':0, 'y3':10, 'x4':1, 'y4':1},
    {'manager':'Julie', 'x1':0, 'y1':80, 'x2':1, 'y2':1, 'x3':0, 'y3':90, 'x4':1, 'y4':1}
];

问题

如何合并对象,以便只有具有相同 manager 值的对象才能在我的数组中相互合并?

【问题讨论】:

    标签: javascript object


    【解决方案1】:

    从其中一个列表中,创建一个由manager 索引的对象。然后,在遍历另一个列表时,只需查找相同的 manager 属性并合并:

    var tempList1 = [
       {'manager':'John', 'x1':0, 'y1':0, 'x2':1, 'y2':1},
       {'manager':'Tom', 'x1':0, 'y1':50, 'x2':1, 'y2':1},
       {'manager':'Julie', 'x1':0, 'y1':80, 'x2':1, 'y2':1}
    ];
    
    var tempList2 = [
       {'manager':'Tom', 'x3':0, 'y3':10, 'x4':1, 'y4':1},
       {'manager':'Julie', 'x3':0, 'y3':90, 'x4':1, 'y4':1},
       {'manager':'John', 'x3':0, 'y3':50, 'x4':1, 'y4':1}
    ];
    
    const list1ByManager = tempList1.reduce((a, item) => {
      a[item.manager] = item;
      return a;
    }, {});
    
    const combined = tempList2.map((item2) => ({
      ...list1ByManager[item2.manager],
      ...item2
    }));
    
    console.log(combined);

    【讨论】:

    • 我不知道为什么,但所有y1y2 值都以相同的值结束——属于最后一个经理的值。这在某种程度上很重要吗?在您的代码之前,所有y1s 和y2s 都被保留了。我想知道是什么让它们截断到最后一个值?
    • 在输入中,tempList1 的第一个和第三个对象的 x1y1 属性相同 (0),因此它们在输出中也相同。 (tempList1 中的Tom 对象与tempList2 中的Tom 对象相同,并且没有x1y1 属性)
    • 抱歉,我的意思是让 Tom 拥有 x1y1。我更新了示例代码以更准确地反映我的实际数据。
    • 看起来可以按需要工作。 tempList1 中的不同 y1 属性都被复制到 combined 数组中的适当其他对象。
    • 您可能是对的,但错误仍然存​​在。如果你好奇的话,我已经用我的完整数据更新了*.com/questions/57386189/d3-append-many-short-paths这篇文章。我承认代码有点长...
    【解决方案2】:

    由于您需要每个管理有一个案例,我将您的数组转换为以经理姓名为键的对象,然后再次转换为对象数组

    var tempList1 = [
      {'manager':'John', 'x1':0, 'y1':0, 'x2':1, 'y2':1},
      {'manager':'Tom', 'x3':0, 'y3':0, 'x4':1, 'y4':1},
      {'manager':'Julie', 'x1':0, 'y1':0, 'x2':1, 'y2':1},
    ].reduce(function(result, obj) {
      result[obj.manager] = obj
      return result
    }, {});
    
    console.log(tempList1)
    
    var tempList2 = [
      {'manager':'Tom', 'x3':0, 'y3':0, 'x4':1, 'y4':1},
      {'manager':'Julie', 'x3':0, 'y3':0, 'x4':1, 'y4':1},
      {'manager':'John', 'x3':0, 'y3':0, 'x4':1, 'y4':1},
    ].reduce(function(result, obj) {
      result[obj.manager] = obj
      return result
    }, {});
    
    var temp = []
    
    for (var key in tempList1) {
      temp.push({ ...tempList1[key], ...tempList2[key] })
    }
    
    console.log(temp)

    【讨论】: