5

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));

6
  • What do you want the output to be? What should result be? 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. Commented Jan 23, 2019 at 7:01
  • @JackBashford - I got the expected output. Just want to reduce the code with efficient and performance way. 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... Commented Jan 23, 2019 at 7:05
  • @RSKMR Is ordering of elements fixed i.e. first elements of arrayList1 and then arrayList2? Commented Jan 23, 2019 at 7:05

4 Answers 4

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; }

Sign up to request clarification or add additional context in comments.

1 Comment

Since Object.values does not guarantee to come in any particular order I would suggest using a Map instead: [ ...[] .concat(arrayList1, arrayList2) .reduce((r, c) => r.set(c.type, Object.assign(r.get(c.type) || {}, c)), r, new Map()) .values(), ];
1

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}))

1 Comment

See comment at Mohammad Usman answer; the order is not guaranteed in Object.values so if order is important and you want it guaranteed then it's better to use Map.
0

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));

1 Comment

The expected output not met. Please check my output in question.
0

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.