0

My function takes an array of arrays and returns the merged array without duplicates

function mergeArrayOfPrimitives<T>(
  primitiveArraysTobeMerged: Array<Array<T>>
): Array<T> {
  const merged: Array<T> = [];
  primitiveArraysTobeMerged.forEach((primitiveArray: Array<T>) =>
    [...merged].concat([...primitiveArray])
  );
  return [...new Set([...merged])];
}

But when I test it on typescript playground with below inputs, it returns [] instead of ['CORE - AGILE']

console.log(mergeArrayOfPrimitives([[], ['CORE - AGILE']])); ==> [LOG]: []
izengod
  • 1,116
  • 5
  • 17
  • 41
  • concat returns new array. you are not doing anything to merged here basically. perhaps you could try `merged.push(...primitiveArray)` – cmgchess Apr 21 '23 at 08:46
  • @cmgchess [...merged, ...primitiveArray] also returns same result – izengod Apr 21 '23 at 08:49
  • @cmgchess Is there a way to do it immutably? push will alter the original array – izengod Apr 21 '23 at 08:50
  • original array here means? – cmgchess Apr 21 '23 at 08:51
  • the merged array – izengod Apr 21 '23 at 08:54
  • how about a `let merged = []` and then reassign `merged =[...merged].concat...` – cmgchess Apr 21 '23 at 09:06
  • `concat` returns a new array, you're not doing anything with the result. – nullptr Apr 21 '23 at 09:16
  • You only need one temporary object - the deduplication set. You can add all elems one by one - they will be iterated in inserion order. See: https://tsplay.dev/w22L4w – Lesiak Apr 21 '23 at 09:46
  • Thank you @Lesiak Please add it to the answer I will accept this. – izengod Apr 21 '23 at 10:05
  • You aren't assigning the result of your concat to anything. Also there is no reason not to mutate `merged`, it's just a waste to repeatedly make copies of your arrays. You can just call a single concat `return [...new Set([].concat(...primitiveArraysTobeMerged))];` here using spread syntax to spread the passed 2d array, not to create a copy of it. – pilchard Apr 21 '23 at 10:11
  • Thanks @pilchard I think the simplest solution will be return [...new Set(...primitiveArraysTobeMerged)]; – izengod Apr 21 '23 at 10:20
  • @izengod that isn't what I said and that won't achieve your goal. A set operating on arrays will not dedupe them. You'll note my comment includes a `concat` call on the spread arrays. – pilchard Apr 21 '23 at 10:50

1 Answers1

1

Your solution fails as you ignore the result of concat: The concat() method is used to merge two or more arrays. This method does not change the existing arrays, but instead returns a new array.

On top of that, your solution seems to create a lot of temporary arrays - none of which is necessary.

You only need one temporary object - the deduplication set. You can add all elems one by one - they will be iterated in insertion order. See Why does JS keep insertion order in Set?

Set API is minimalistic - you need a foreach loop to add all elements form an array. See How to add an array of values to a Set

function mergeArrayOfPrimitives<T>(
  primitiveArraysTobeMerged: Array<Array<T>>
): Array<T> {
  const dedupSet = new Set<T>();
  primitiveArraysTobeMerged.forEach(a => a.forEach(dedupSet.add, dedupSet));
  return [...dedupSet];
}

Playground link

Lesiak
  • 22,088
  • 2
  • 41
  • 65