kayakaya
kayakaya

Reputation: 49

Remove equal objects from array

I have the following problem in JavaScript: I want to check an array for duplicates. My example array only has 6 objects here.

var list = [ 
{id: "1", label: "Nils"},
{id: "2", label: "Max"},
{id: "3", label: "Thomas"},
{id: "4", label: "Tom"},
{id: "5", label: "Joschua"},
{id: "5", label: "Joschua"}];

In the later project it can also be more than 500, which I import via a CSV file. And now I want to remove duplicates. At first I tried the set method:

var newList = [... new Set(list)];
console.log(newList);

The result is false. The array has the same objects.

Then I tried a simple if query:

if(list[4]==list[5]){
console.log("equal") }else{
console.log("unequal")}

The result is unequal. I don't understand why.

The array should look like this:

[{ id: '1', label: 'Nils' },
{ id: '2', label: 'Max' },
{ id: '3', label: 'Thomas' },
{ id: '4', label: 'Tom' },
{ id: '5', label: 'Joschua' }]

Upvotes: 1

Views: 64

Answers (3)

Aalexander
Aalexander

Reputation: 5004

Then I tried a simple if query:

if(list[4]==list[5]){ console.log("equal") }else{ console.log("unequal")} The result is unequal. I don't understand why.

== uses Abstract Equality Comparison Algorithm.

  • At first this algorithm checks if the types are the same -> which they are.
  • Then the algorithm proceeds with the first step, and goes down to check if they both referencing the same object -> they don't referencing the same object

That is the reason why it prints out false

Each usage of {} creates a new object, so this check fails and the result is false.

let a = {}
let b = {}

console.log(a==b);

Or like in your example

let a = {id: "5", label: "Joschua"};
let b = {id: "5", label: "Joschua"};

console.log(a==b);

Solution

To check if two objects are equal you can do the following

   let a = {
      id: 5,
      name: "Max"
    }
    let b = {
      id: 5,
      name: "Max"
    }

    function areTheObjectsEqual(obj1, obj2) {
      let keysObj1 = Object.keys(obj1);
      let keysObj2 = Object.keys(obj2);

      // first check if they have the same amount of keys, if not return false
      if (keysObj1.length !== keysObj2.length) {
        return false;
      } 
      
      let valuesObj1 = Object.values(obj1);
      let valuesObj2 = Object.values(obj2);
      
      // then compare if they have the same values
      for(let i = 0; i < valuesObj1.length; i++){
        if(valuesObj1[i] !== valuesObj2[i]){
          return false;
        }
      }
      return true;
    }

    console.log(areTheObjectsEqual(a,b));

Upvotes: 1

Orelsanpls
Orelsanpls

Reputation: 23515

Set cannot compare object altogether, it only works with primitives types like number or string.

You can use a Map that is based on a key/value paradigm though, like :

const list = [ 
  {id: '1',label: 'Nils'},
  {id: '2', label: 'Max'},
  {id: '3', label: 'Thomas'},
  {id: '4', label: 'Tom'},
  {id: '5', label: 'Joschua'},
  {id: '5', label: 'Joschua'},
];

const map = new Map();

// Push the values into the map
list.forEach(({
  id,
  label,
}) => map.set(id, label));

// Transform the map into an array of object
const uniqueList = Array.from(map, ([id, label]) => ({
  id,
  label,
}));

console.log(uniqueList);


Or using an Array.reduce combined with an Array.map

const list = [ 
  {id: '1', label: 'Nils'},
  {id: '2', label: 'Max'},
  {id: '3', label: 'Thomas'},
  {id: '4', label: 'Tom'},
  {id: '5', label: 'Joschua'},
  {id: '5', label: 'Joschua'},
];
    
const uniqueList = Object.entries(list.reduce((tmp, {
  id,
  label,
}) => {
  tmp[id] = label;
  
  return tmp;
}, {})).map(([ 
  id,
  label,
 ]) => ({
  id,
  label,
}));

console.log(uniqueList);


Upvotes: 1

Unmitigated
Unmitigated

Reputation: 89264

If the ids are meant to be unique, you can use Array#filter with a Set based on the id.

var list = [ 
{id: "1", label: "Nils"},
{id: "2", label: "Max"},
{id: "3", label: "Thomas"},
{id: "4", label: "Tom"},
{id: "5", label: "Joschua"},
{id: "5", label: "Joschua"}];
const set = new Set,
      res = list.filter(x => !set.has(x.id) && set.add(x.id));
console.log(res);

Upvotes: 2

Related Questions