Tyler Morales
Tyler Morales

Reputation: 1848

How to merge an array of objects into one array and then filter out the duplicates

Firstly, I am trying to merge an array of many objects into a single array with every key in each object.

Lastly, any duplicate items in the array should be removed as well as any elements named "name".

Input:

const data = [
  {
    name: '10/20',
    Tyler: 1,
    Sonia: 0,
    Pedro: 0,
  },
  {
    name: '10/23',
    Tyler: 0.5,
    Sonia: 0.25,
    Pedro: 0.75,
    George: 0.5,
  },
];

Output:

["Tyler", "Sonia", "Pedro", "George"]

This is what I've tried so far:

const mergedData = data.reduce((prev, cur) => {
  const obj = cur[0];
  const keys = Object.keys(obj);
  const names = keys.splice(1);
  return { names };
}, []);

I am trying to capture any key name other than "name" and add it to the final array. However, this is where I get stuck because I get this error, TypeError: Cannot convert undefined or null to object

Note: Objects may be different lengths, contain a mix of names, but never any duplicates.

Upvotes: 0

Views: 89

Answers (2)

TylerSmall19
TylerSmall19

Reputation: 155

If you have access to ES6 methods, you can do this using a Set (unique values are ensured at creation) and converting it back into an array if you want through Destructuring.

data = [{name: '0', Tyler: '1', Dan: '2', Carl: '3'},  {name: '0', Tyler: '1', Dan: '2', Eric: '3', Danny: '4'}];

const output = (data) => {
  let output = [];

  // This makes sure you get each array and then strips just the keys as desired
  data.forEach(item => {
      output = output.
        concat(Object.keys(item))
  });

// This creates the set, strips our dups, and then spreads itself into an array
return [...new Set(output)]
    // Strip out the 'name' key as needed
    // NOTE: This should be a param instead of hard-coded, but this is easier to show
    .filter(res => res != 'name');
}

console.log(output(data));

This should be fairly performant considering it only navigates the full array one time and each object itself shouldn't have millions of properties to cause .keys() any issues.

Upvotes: 1

ProDec
ProDec

Reputation: 5410

An option is to find all keys put in a set and remove the name key

const data = [
  {
name: '10/20',
Tyler: 1,
Sonia: 0,
Pedro: 0,
  },
  {
name: '10/23',
Tyler: 0.5,
Sonia: 0.25,
Pedro: 0.75,
George: 0.5,
  },
];

const set = new Set(data.reduce((acc, i) => [...acc, ...Object.keys(i)], []));
set.delete('name');
const result = [...set];

console.log(result);

Upvotes: 1

Related Questions