在JavaScript中合并2个嵌套对象

uyto3xhc  于 2023-10-14  发布在  Java
关注(0)|答案(4)|浏览(89)
const obj1 = {
    prop1: 'value1',
    prop2: 'value2',
    prop3: { prop4: 'value4', prop5: {
         prop5: 'value5'
         } 
    },
}
const obj2 = {
    prop6: 'value6',
    prop2: 'value2',
    prop7: { prop8: 'value8', prop9: {
         prop10: 'value10'
         } 
    },
}

我在JavaScript中有两个嵌套的对象,我想把它们合并成一个对象。有的对象属性相同,有的不相同;我想把它们合并,这样相同的就能保留下来。如何合并这两个嵌套很深的对象?

2jcobegt

2jcobegt1#

关于合并,我们通常有两种方法,Shallow merge and Deep Merge。对于浅合并,JavaScript有这些方法。

  1. Object.assign()
    1.通过spread operator合并
    但是如果你想深度合并,你应该遍历一个对象的所有项,然后一个接一个地合并它们(递归合并),或者使用像Lodash这样的伟大库
  2. Sample of Deep Merging with Lodash
    1.如何深度合并JavaScript对象?
vlju58qv

vlju58qv2#

如果有人想将两个Object合并成一个Object,而不使用任何Library,比如Lodash,那么你可以像下面这样做

function deepMergeObjects(obj1, obj2) {
    const result = {};

    for (const key in obj2) {
        if (obj2.hasOwnProperty(key)) {
            if (typeof obj2[key] === "object" && obj1.hasOwnProperty(key) && typeof obj1[key] === "object") {
                result[key] = deepMergeObjects(obj1[key], obj2[key]);
            } else {
                result[key] = obj2[key];
            }
        }
    }

    for (const key in obj1) {
        if (obj1.hasOwnProperty(key) && !result.hasOwnProperty(key)) {
            if (typeof obj1[key] === "object") {
                result[key] = deepMergeObjects(obj1[key], {});
            } else {
                result[key] = obj1[key];
            }
        }
    }

    return result;
}

const obj1 = {
    a: 1,
    b: {
        c: 2,
        d: 3,
    },
    test1: null,
    test2: {},
    test3: {},
    test4: false,
    test5: undefined
};

const obj2 = {
    b: {
        d: 4,
        e: 5,
    },
    f: 6,
    test1: {},
    test2: null,
    test3: false,
    test4: {},
    test5: {}
};

console.time("time");
const mergedObject = deepMergeObjects(obj1, obj2);
console.timeEnd("time");
console.log(JSON.stringify(mergedObject));

另外如果任何人需要覆盖或添加values of obj1 into obj2,那么你可以像下面这样做
**方法一:-**使用ForLoop覆盖或添加values of obj1 into obj2

function deepMergeObjects(obj1, obj2) {
    for (const key in obj1) {
        if (obj1.hasOwnProperty(key)) {
            if (typeof obj1[key] === "object") {
                if (typeof obj2[key] !== "object" || Array.isArray(obj2[key])) {
                    obj2[key] = Array.isArray(obj1[key]) ? [] : {};
                }
                deepMergeObjects(obj1[key], obj2[key]);
            } else {
                obj2[key] = obj1[key];
            }
        }
    }
}

const obj1 = {
    a: 1,
    b: {
        c: 2,
        d: 3,
    },
    test1: null,
    test2: {},
    test3: {},
    test4: false,
    test5: undefined
};

const obj2 = {
    b: {
        d: 4,
        e: 5,
    },
    f: 6,
    test1: {},
    test2: null,
    test3: false,
    test4: {},
    test5: {}
};

console.time("time");
deepMergeObjects(obj1, obj2);
console.timeEnd("time");
console.log(JSON.stringify(obj2));

**方法二:-**递归Set Object覆盖或添加values of obj1 into obj2

const deepMerge = (a, b, fn) =>
  [...new Set([...Object.keys(a), ...Object.keys(b)])].reduce((acc, key) => {
    if (a.hasOwnProperty(key) && b.hasOwnProperty(key)) {
      if (a[key] === null || a[key] === undefined) {
        acc[key] = b[key];
      } else if (b[key] === null || b[key] === undefined) {
        acc[key] = a[key];
      } else if (typeof a[key] === "object" && typeof b[key] === "object") {
        acc[key] = deepMerge(a[key], b[key], fn);
      } else {
        acc[key] = fn(key, a[key], b[key]);
      }
    } else if (a.hasOwnProperty(key)) {
      acc[key] = a[key];
    } else {
      acc[key] = b[key];
    }
    return acc;
  }, {});

const obj1 = {
    a: 1,
    b: {
        c: 2,
        d: 3,
    },
    test1: null,
    test2: {},
    test3: {},
    test4: false,
    test5: undefined
};

const obj2 = {
    b: {
        d: 4,
        e: 5,
    },
    f: 6,
    test1: {},
    test2: null,
    test3: false,
    test4: {},
    test5: {}
};

console.time("time");
const mergedObject = deepMerge(obj1, obj2, (key, a, b) => {
  if (typeof a === "object") {
    return Array.isArray(a) ? [] : {};
  } else {
    return b;
  }
});
console.timeEnd("time");

console.log(JSON.stringify(mergedObject));

我希望这对你有帮助

快乐编码:)

ac1kyiln

ac1kyiln3#

在Deno中,您可以使用deepMerge-
合并两个给定的记录,递归地合并任何嵌套的记录,如果发生冲突,第二个集合将覆盖第一个集合

import { deepMerge } from "https://deno.land/std/collections/mod.ts"

const o3 = deepMerge(o1, o2)
jogvjijk

jogvjijk4#

递归合并数组和对象

const obj1 = {
  prop1: 'value1',
  prop2: 'value2',
  prop3: {
    prop4: 'value4',
    prop5: {
      prop5: 'value5'
    },
    a: ['a', 'b']
  },
}

const obj2 = {
  prop6: 'value6',
  prop2: 'value2',
  prop7: {
    prop8: 'value8',
    prop9: {
      prop10: 'value10'
    }
  },
  prop3: {
    prop9: 'value9',
    prop8: {
      prop7: 'value7',
      prop8: {
        prop7: 'value7'
      }
    },
    a: ['a', 'b']
  },
}

const Merge = (object1, object2) => {
  if (Array.isArray(object2)) {
    return [...object1, ...object2]
  } else {
    return Object.entries(object2).reduce((acc, [key, value]) => {
      if (
        Object.keys(acc).includes(key) &&
        typeof value === 'object'
      ) {
        acc[key] = Merge(acc[key], value)
      } else {
        acc[key] = value
      }
      
      return acc
    }, { ...object1 })
  }
}

const result = Merge(obj1, obj2)

console.log(result)

相关问题