0

I am very new to javascript, my question is I have an array of objects. Is it possible to filter duplicate objects from an Array by using filter method. I know how to remove duplicates from an Array with filter method. So help me to achieve this.

This is my code

const students = [
    {
        name: 'Mark',
        age: 21
    },
    {
        name: 'Williams',
        age: 27
    },
    {
        name: 'Mark',
        age: 21
    }
]
  • You need to compare objects for equality. https://stackoverflow.com/q/201183/2025923 & https://stackoverflow.com/q/1068834/2025923 – Tushar Nov 13 '19 at 05:14
  • 5
    `Is it possible to filter duplicate objects from an Array by using filter method` - yes, that's what it's for .... `I know how to remove duplicates from an Array with filter method` ... so why did you ask? – Bravo Nov 13 '19 at 05:16
  • Hi @Bravo I know how to remove duplicates in an Array, But I don't know how to remove duplicates from an Array of objects. I tried it but its not working fine. –  Nov 13 '19 at 05:19
  • `I tried` - you should show what you tried, otherwise it's just you saying you tried – Bravo Nov 13 '19 at 05:26
  • Please add the expected output so that we can close it with an appropriate duplicate. – adiga Nov 13 '19 at 06:51

4 Answers4

1

You may use a Data structure called HashMap, in Javascript can be represented as a simple object.

const students = [
    {
        name: 'Mark',
        age: 21
    },
    {
        name: 'Williams',
        age: 27
    },
    {
        name: 'Mark',
        age: 21
    }
];

// simple object that represents our hashmap, a data structure that let us access in O(1) time the value in a given key
const hash = {};

const filteredStudents = students.filter(({name, age}) => {
  const key = `${name}${age}`; // using the combination of name + age as a key in our hashmap
  
  if (key in hash) { // if exist this means we do not wanted to included in our filteredStudents
    return false;
  }
  
  // We set the value true to our object so next time it checks key in hash is going to find the key and won't continue here
  hash[key] = true;
  
  // If the value is not found until here it means that was not found as a key in our object
  return true;
  
});


console.log(filteredStudents);

And problem solved!

ricardoorellana
  • 2,270
  • 21
  • 35
0

An ES6 way of doing this

const students = [
  {
    name: "Mark",
    age: 21
  },
  {
    name: "Williams",
    age: 27
  },
  {
    name: "Mark",
    age: 21
  }
];

const unique = [...new Set(students.map(JSON.stringify))].map(JSON.parse);

If your students array will have objects like {age: 21, name: "Mark"}, use

const unique = [...new Set(students.map(i => JSON.stringify({name: i.name, age: i.age})))].map(JSON.parse);
Abito Prakash
  • 4,368
  • 2
  • 13
  • 26
  • 2
    to see why this answer is wrong, try changing the last object to `{age: 21, name: "Mark" }` – Bravo Nov 13 '19 at 05:27
  • the better ES6 way (for simple objects, of course) is `const unique = [...new Set(students.map(o => JSON.stringify(Object.fromEntries(Object.entries(o).sort(([a],[b])=>a.localeCompare(b))))))].map(JSON.parse);` – Bravo Nov 13 '19 at 05:33
  • Thanks for the catch @Bravo, I have edited the answer to include that case also – Abito Prakash Nov 13 '19 at 05:37
0

There's a lib call fast-json-stable-stringify I used alot for multiple purposes. You can use it to do shape-equality check against objects.

const stringify = require('fast-json-stable-stringify')
const seen = {}

const deduped = students.filter((item) => {
  const key = stringify(item)
  if (seen[key]) {
    return false
  } else {
    seen[key] = true
    return true
  }
})

JSON.stringify from standard lib is not stable, so don't rely on it to yield same key for two objects of same shape.

Fact check:

JSON.stringify({ foo: 'bar', zoo: 1 })
=> '{"foo":"bar","zoo":1}'
JSON.stringify({ zoo: 1, foo: 'bar' })
=> '{"zoo":1,"foo":"bar"}'
hackape
  • 18,643
  • 2
  • 29
  • 57
0

While I know you asked for the filter method, if you using lodash.js, like most projects are, you can use the following: _.uniqWith(students, _.isEqual)

const students = [
    {
        name: 'Mark',
        age: 21
    },
    {
        name: 'Williams',
        age: 27
    },
    {
        name: 'Mark',
        age: 21
    }
]

console.log(_.uniqWith(students, _.isEqual));

Fiddle here

Samuel Goldenbaum
  • 18,391
  • 17
  • 66
  • 104