两个对象key相同的,值进行合并?

const a = {
  fruits: ['apple', 'banana'],
  series: {
    apple: ['C'],
    banana: ['A', 'B'],
  }
};
const b = {
  fruits: ['banana', 'orange'],
  animals: ['pig'],
  series: {
    banana: ['B', 'C'],
    orange: ['A'],
  }
}
const merge = (a, b) => {
  //...
}
// 期望输出:
{
  fruits: ['apple', 'banana', 'orange'],
  animals: ['pig'],
  series: {
    apple: ['C'],
    banana: ['A', 'B', 'C'],
    orange: ['A'],
  }
}
阅读 3.1k
5 个回答
const merge = (a, b) => {
  const result = {};
  for (const key of Object.keys(a)) {
    if (b.hasOwnProperty(key)) {
      if (Array.isArray(a[key])) {
        result[key] = [...new Set([...a[key], ...b[key]])];
      } else if (typeof a[key] === 'object') {
        result[key] = merge(a[key], b[key]);
      } else {
        result[key] = b[key];
      }
    } else {
      result[key] = a[key];
    }
  }
  for (const key of Object.keys(b)) {
    if (!a.hasOwnProperty(key)) {
      result[key] = b[key];
    }
  }
  return result;
}
function merge(target,source) {
  return Object.keys(source).reduce((res,k) => {
    res[k] = k in target ? Array.isArray(res[k]) ? [...new Set(source[k].concat(target[k]))] : typeof res[k] == 'object' ? merge(res[k],source[k]) : res[k] : source[k]
    return res;
  }, JSON.parse(JSON.stringify(target))); // 为了不影响目标对象,做一次拷贝
}
             

仅针对示例,如果还要考虑数组内对象的合并,以及null/undefined的考虑都需要再优化下代码

引入 lodash 库 解决这种问题比较方便

const a = {
  fruits: ['apple', 'banana'],
  series: {
    apple: ['C'],
    banana: ['A', 'B'],
  }
};

const b = {
  fruits: ['banana', 'orange'],
  animals: ['pig'],
  series: {
    banana: ['B', 'C'],
    orange: ['A'],
  }
}



function customizer(objValue, srcValue) {
  if (_.isArray(objValue)) {
    return _.union(objValue,srcValue)
  }
}
const d= _.mergeWith(a,b,customizer)

console.log(d)

假定值只为 arrayobject。下列代码会修改 a

let merge = (a, b) => Array.isArray(b) ? [...new Set(a.concat(b))] : Object.entries(b).reduce((a, [k, v]) => {a[k] = merge(a[k] ?? v, v); return a}, a);

不是很复杂的,参考以下代码:

function mergeObjects(a, b) {
  return Object.assign({}, a, b, (obj, src) => {
    if (Array.isArray(src)) {
      return [].concat(obj, src);
    } else if (typeof src === 'object') {
      return Object.assign({}, obj, src, mergeObjects);
    } else {
      return src;
    }
  });
}

const a = {
  fruits: ['apple', 'banana'],
  series: {
    apple: ['C'],
    banana: ['A', 'B'],
  }
};
const b = {
  fruits: ['banana', 'orange'],
  animals: ['pig'],
  series: {
    banana: ['B', 'C'],
    orange: ['A'],
  }
};

const result = mergeObjects(a, b);
console.log(result);
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏