0

I have an array of objects that have duplicate unique id's due to a join with another data set. This is due to the limitation of the API returning the data. What I want to do is to find duplicate rows and join the unique column of data in JavaScript. As an example, this is what I have:

var data = [
  {id: 1, name: 'Joe', type:'Red'},
  {id: 2, name: 'Smith', type:'Red'},
  {id: 2, name: 'Smith', type:'Green'},
  {id: 3, name: 'Ana', type:'Blue'},
];

this is the result I need:

var data = [
  {id: 1, name: 'Joe', type:'Red'},
  {id: 2, name: 'Smith', type:'Red, Green'},
  {id: 3, name: 'Ana', type:'Blue'},
];

I figured I could create a nested for loop but I believe performance wise it wouldn't be ideal. I tried using the Array.prototype.filter but couldn't achieve what I needed here.

2
  • Why not an array of types? Commented Nov 9, 2018 at 22:19
  • I need to bind the objects to a table (JQuery table) so they are all string or int. But if you have an implementation that would result it to be an array I could possibly call the join function before binding to put it back into one comma separated string Commented Nov 9, 2018 at 22:28

2 Answers 2

3

I recommend you to use an array of types, it's cleaner and reusable.

This approach uses the function Array.prototype.reduce to group the objects by id and the function Object.values to extract the grouped objects.

var data = [  {id: 1, name: 'Joe', type:'Red'},  {id: 2, name: 'Smith', type:'Red'},  {id: 2, name: 'Smith', type:'Green'},  {id: 3, name: 'Ana', type:'Blue'}],
    result = Object.values(data.reduce((a, c) => {
      (a[c.id] || (a[c.id] = Object.assign({}, c, {type: []}))).type.push(c.type);

      return a;
}, Object.create(null)));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

3 Comments

Nice idea using the short-circuit to populate the object if the key didn't exist and immediately hopping into array methods!
My array has a GUID as the id field, not an incremental int. Would this still work? I gave it a try and the array was returning as undefined.
Thank you so much! Your answer worked and now I know about the Array.prototype.reduce method.
3

You can do this with reduce wrapped with Object.values:

var data = [ {id: 1, name: 'Joe', type:'Red'}, {id: 2, name: 'Smith', type:'Red'}, {id: 2, name: 'Smith', type:'Green'}, {id: 3, name: 'Ana', type:'Blue'}, ];

const result = Object.values(data.reduce((r,c) => 
  (r[c.id] ? r[c.id].type = `${r[c.id].type}, ${c.type}` : r[c.id] = c, r), {}))

console.log(result)

The idea is to check in the reduce if the key exists and if so simply concat the types string if not set the key.

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.