You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于相同键值合并对象数组,多匹配时按优先级合并(JS)

在JavaScript中按指定优先级合并对象数组

需求说明

基于对象数组的相同键值(数组a的x与数组b的x1)合并两个对象数组;当存在多个匹配项时,按照给定的priority数组规则选择最高优先级的项完成合并。

示例数据

数组a(x值唯一)

const a = [
  { x: 'all', y: 'tablename', z: 'schema' },
  { x: 'all1', y: 'tablename', z: 'schema' },
  { x: 'all2', y: 'tablename', z: 'schema' },
  { x: 'al52', y: 'tablename', z: 'schema' },
];

数组b

const b = [
  { x1: 'all', y1: 'tablename', z1: 'schema' },
  { x1: 'all', y1: 'tablename1', z1: 'schema1' },
  { x1: 'all1', y1: 'tablename1', z1: 'schema1' },
  { x1: 'all', y1: 'tablename3', z1: 'schema' },
  { x1: 'all1', y1: 'tablename2', z1: 'schema1' },
];

优先级规则数组priority

优先级从高到低排列,匹配时优先选择排在前面的项:

const priority = [
  { y1: 'tablename3', z1: 'schema' },
  { y1: 'tablename1', z1: 'schema1' },
  { y1: 'tablename2', z1: 'schema' },
  { y1: 'tablename', z1: 'schema' },
];

预期合并结果

const expected = [
  {
    x: 'all',
    y: 'tablename',
    z: 'schema',
    x1: 'all',
    y1: 'tablename3',
    z1: 'schema',
  },
  {
    x: 'all1',
    y: 'tablename1',
    z: 'schema1',
    x1: 'all1',
    y1: 'tablename1',
    z1: 'schema1',
  },
];

当前问题

现有代码仅匹配到第一个符合x === x1的项就停止遍历,未按照优先级规则筛选最优项,导致输出结果不符合预期:

实际输出结果

const actual = [
  {
    x: 'all',
    x1: 'all',
    y: 'tablename',
    y1: 'tablename',
    z: 'schema',
    z1: 'schema',
  },
  {
    x: 'all1',
    x1: 'all1',
    y: 'tablename',
    y1: 'tablename1',
    z: 'schema',
    z1: 'schema1',
  },
];

现有代码

var c = [];
for (var i = 0; i < a.length; i++) {
  for (var j = 0; j < b.length; j++) {
    if (a[i].x === b[j].x1) {
      var combinedObj = {
        x: a[i].x,
        y: a[i].y,
        z: a[i].z,
        x1: b[j].x1,
        y1: b[j].y1,
        z1: b[j].z1,
      };
      c.push(combinedObj);
      break;
    }
  }
}
console.log(c);

修改方案

核心思路是先为优先级规则建立快速查找的映射,再对每个a的项筛选所有匹配的b项,最后选出优先级最高的项完成合并(从预期结果看,合并时a的y、z需要替换为选中b项的y1、z1)。

修改后的代码

// 1. 建立优先级映射:将{y1,z1}组合映射为优先级分数(分数越高优先级越高)
const priorityMap = new Map();
priority.forEach((item, index) => {
  const key = `${item.y1}-${item.z1}`;
  // 用数组长度减去索引值作为分数,越靠前的项分数越高
  priorityMap.set(key, priority.length - index);
});

const result = [];

// 2. 遍历数组a的每个项
for (const itemA of a) {
  // 筛选出b中所有x1与itemA.x匹配的项
  const matchedItems = b.filter(itemB => itemB.x1 === itemA.x);
  
  // 无匹配项则跳过(按预期结果只保留有匹配的项)
  if (matchedItems.length === 0) continue;
  
  // 3. 从匹配项中选出优先级最高的项
  const highestPriorityItem = matchedItems.reduce((prev, curr) => {
    const prevKey = `${prev.y1}-${prev.z1}`;
    const currKey = `${curr.y1}-${curr.z1}`;
    return priorityMap.get(prevKey) > priorityMap.get(currKey) ? prev : curr;
  });
  
  // 4. 合并对象:保留a的x,替换y、z为b的y1、z1,同时加入b的所有字段
  const merged = {
    x: itemA.x,
    y: highestPriorityItem.y1,
    z: highestPriorityItem.z1,
    x1: highestPriorityItem.x1,
    y1: highestPriorityItem.y1,
    z1: highestPriorityItem.z1,
  };
  
  result.push(merged);
}

console.log(result);

代码说明

  • 优先级映射:把priority数组中的每个{y1,z1}组合转换为唯一键,用反向索引值作为优先级分数,实现快速的优先级比较。
  • 筛选匹配项:对每个a的项,找出所有b中x1匹配的项,避免只取第一个匹配项的问题。
  • 选择最优项:通过reduce遍历匹配项,选出优先级分数最高的项。
  • 合并对象:按照预期结果的格式,完成对象合并并加入结果数组。

内容的提问来源于stack exchange,提问作者Suparna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 07:59:53