最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to merge and replace objects from two arrays based on a key in javascript? - Stack Overflow

programmeradmin5浏览0评论

I have two array object(arrayList1,arrayList2). Just I am trying to merge those two arrays into one array object. The following terms I used.

  • Both array merged into one array based on key-name is type.
  • arrayList2 values will be overwrite the arrayList1.
  • I Got the expected output but I am worying to do with efficient and performance way..

Can someone please simplify my code..

Note :

  • It would be great if using Array.reduce function and without use any plugin/library..
  • I added the smaple input for understanding. The element order will be change and size of both array's will change.

const arrayList1 = [
    { type: "A", any: 11, other: "ab", props: "1" },
    { type: "B", any: 22, other: "bc", props: "2" }, // same type
    { type: "C", any: 33, other: "df", props: "3" }
];
 
const arrayList2 = [
    { type: "D", any: 44, other: "aa", props: "11" },
    { type: "B", any: 22, other: "bb", props: "2----2" , x: 10}, // same type
    { type: "E", any: 44, other: "cc", props: "33" }
];

result = arrayList2.reduce(function (arr1, arr2) {
  let isMatchFound = false;
  arr1.forEach(function (list) {
    if (arr2.type == list.type) {
      list = Object.assign(list, arr2);
      isMatchFound = true;
    }
  });
  if (!isMatchFound) {
    arr1.push(arr2);
  }
  return arr1;
}, arrayList1);

console.log('result', JSON.stringify(result));

I have two array object(arrayList1,arrayList2). Just I am trying to merge those two arrays into one array object. The following terms I used.

  • Both array merged into one array based on key-name is type.
  • arrayList2 values will be overwrite the arrayList1.
  • I Got the expected output but I am worying to do with efficient and performance way..

Can someone please simplify my code..

Note :

  • It would be great if using Array.reduce function and without use any plugin/library..
  • I added the smaple input for understanding. The element order will be change and size of both array's will change.

const arrayList1 = [
    { type: "A", any: 11, other: "ab", props: "1" },
    { type: "B", any: 22, other: "bc", props: "2" }, // same type
    { type: "C", any: 33, other: "df", props: "3" }
];
 
const arrayList2 = [
    { type: "D", any: 44, other: "aa", props: "11" },
    { type: "B", any: 22, other: "bb", props: "2----2" , x: 10}, // same type
    { type: "E", any: 44, other: "cc", props: "33" }
];

result = arrayList2.reduce(function (arr1, arr2) {
  let isMatchFound = false;
  arr1.forEach(function (list) {
    if (arr2.type == list.type) {
      list = Object.assign(list, arr2);
      isMatchFound = true;
    }
  });
  if (!isMatchFound) {
    arr1.push(arr2);
  }
  return arr1;
}, arrayList1);

console.log('result', JSON.stringify(result));

Share Improve this question edited Jan 25, 2019 at 14:02 adiga 35.3k9 gold badges65 silver badges87 bronze badges asked Jan 23, 2019 at 6:58 RSKMRRSKMR 1,8925 gold badges32 silver badges74 bronze badges 6
  • What do you want the output to be? What should result be? – Jack Bashford Commented Jan 23, 2019 at 7:01
  • What is the use case here. What is the typical size of list 1 and list 2? Are they always equal? I won't be too worried about performance until it is a problem. When the codebase is huge, bottlenecks are often some where else. Machine can deal with loops etc pretty efficiently these days. – Samuel Toh Commented Jan 23, 2019 at 7:01
  • @JackBashford - I got the expected output. Just want to reduce the code with efficient and performance way. – RSKMR Commented Jan 23, 2019 at 7:03
  • @SamuelToh, The size of 'list-1' and 'list-2' will be change.. Mostly the format of list1, list2 will be differ. Just I added smaple json for understanding... – RSKMR Commented Jan 23, 2019 at 7:05
  • @RSKMR Is ordering of elements fixed i.e. first elements of arrayList1 and then arrayList2? – Ashish Commented Jan 23, 2019 at 7:05
 |  Show 1 more ment

4 Answers 4

Reset to default 2

You may also use .reduce() and Object.values() methods to get the desired output:

const arrayList1 = [
    { type: "A", any: 11, other: "ab", props: "1" },
    { type: "B", any: 22, other: "bc", props: "2" }, // same type
    { type: "C", any: 33, other: "df", props: "3" }
];
 
const arrayList2 = [
    { type: "D", any: 44, other: "aa", props: "11" },
    { type: "B", any: 22, other: "bb", props: "2----2" , x: 10}, // same type
    { type: "E", any: 44, other: "cc", props: "33" }
];

const result = Object.values(
   [].concat(arrayList1, arrayList2)
     .reduce((r, c) => (r[c.type] = Object.assign((r[c.type] || {}), c), r), {})
);
                 
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

You could do something like this using reduce and Object.values

const array1 = [
    { type: "A", any: 11, other: "ab", props: "1" },
    { type: "B", any: 22, other: "bc", props: "2" }, // same type
    { type: "C", any: 33, other: "df", props: "3" }
];
 
const array2 = [
    { type: "D", any: 44, other: "aa", props: "11" },
    { type: "B", any: 22, other: "bb", props: "2----2" , x: 10}, // same type
    { type: "E", any: 44, other: "cc", props: "33" }
];

const mapped = array1.reduce((a,t)=> (a[t.type] = t, a), {}),
      mapped2 = array2.reduce((a,t)=> (a[t.type] = t, a), {})

console.log(Object.values({...mapped, ...mapped2}))

If you just wanted to make your code smaller:

const arrayList1 = [
    { type: "A", any: 11, other: "ab", props: "1" },
    { type: "B", any: 22, other: "bc", props: "2" }, // same type
    { type: "C", any: 33, other: "df", props: "3" }
];
 
const arrayList2 = [
    { type: "D", any: 44, other: "aa", props: "11" },
    { type: "B", any: 22, other: "bb", props: "2----2" , x: 10}, // same type
    { type: "E", any: 44, other: "cc", props: "33" }
];

result = arrayList2.reduce(function(arr1, arr2) {
  if (arr1.find(({ type }) => type == arr2.type)) {
    arr1[arr1.indexOf(arr1.find(({ type }) => type == arr2.type))] = Object.assign(arr1.find(({ type }) => type == arr2.type), arr2);
    arr1.push(arr2);
  }
  return arr1;
}, arrayList1);

console.log('result', JSON.stringify(result));

If you dont exactly need arrayList1 before arrayList2, you can use this one liner simple approach. What I have done is I have destructured all elements arrayList2 and only those elements of arrayList1 whose key does not exist in arrayList1.

P.S. the problem with reduce is you have to reduce the largest array otherwise you will miss out the elements of bigger Array.

const arrayList1 = [
    { type: "A", any: 11, other: "ab", props: "1" },
    { type: "B", any: 22, other: "bc", props: "2" }, // same type
    { type: "C", any: 33, other: "df", props: "3" }
];
 
const arrayList2 = [
    { type: "D", any: 44, other: "aa", props: "11" },
    { type: "B", any: 22, other: "bb", props: "2----2" , x: 10}, // same type
    { type: "E", any: 44, other: "cc", props: "33" }
];
const output = [...arrayList2, ...arrayList1.filter(el1 => !arrayList2.some(el2 => el2.type === el1.type))]
//[].concat(arrayList2, arrayList1.filter(el1 => !arrayList2.some(el2 => el2.type === el1.type)))

console.log(output)

发布评论

评论列表(0)

  1. 暂无评论