Check possible duplicates javascript array

Viewed 65

How can I check for possible duplicates in an array? The possible duplicates in my case is a match in 2 objects in the array.

For example, I have the input:

const input = [
  {
    id: 1,
    name: "Test 1",
    value: 5,
    date: '2021-01-01'
  },
  {
    id: 2,
    name: "Test 2",
    value: 4,
    date: '2021-01-01'
  },
  {
    id: 3,
    name: "Test 3",
    value: 5,
    date: '2021-01-01'
  },
  {
    id: 4,
    name: "Test 4",
    value: 5,
    date: '2021-03-01'
  },
  {
    id: 5,
    name: "Test 1",
    value: 15,
    date: '2021-01-21'
  },
];

In this case the objects with id 1 and 3 are possible duplicates because they have the same value and date. I'm creating a new array for my output:

let output = [];
for(const x of input) {
  output.push(
    {
      id: x.id,
      name: x.name,
      value: x.value,
      date: x.date,
      duplicate: // here is where I would like to set it to true or false
    }
  );
}

Is there a way to do it without looping the array and check the value and date for every instance?

Thanks

2 Answers

Most efficient way is loop through data once and count instances where date + '|' + value occur.

Then map the data and check the counter for dups

const counter = new Map();

input.forEach(({value,date})=> {
    const key = `${date}|${value}`;
    counter.set(key, (counter.get(key) || 0) + 1);
});

const res = input.map(o => {
    const key = `${o.date}|${o.value}`;
    return {...o, duplicate: counter.get(key) > 1} ;
});



console.log(res)
.as-console-wrapper {max-height: 100%!important;top:0;}
<script>
 const input=[{id:1,name:"Test 1",value:5,date:"2021-01-01"},{id:2,name:"Test 2",value:4,date:"2021-01-01"},{id:3,name:"Test 3",value:5,date:"2021-01-01"},{id:4,name:"Test 4",value:5,date:"2021-03-01"},{id:5,name:"Test 1",value:15,date:"2021-01-21"}];
</script>

Whatever solution you find, it WILL be looping through the array in the back kitchen. That's just the only way. That said here's a solution I find elegant:

let output = [];
for(const x of input) {
  output.push(
    {
      id: x.id,
      name: x.name,
      value: x.value,
      date: x.date,
      duplicate: output.some(e => e.value === x.value && e.date === x.date)
    }
  );
}

EDIT: If you want all occurences to have duplicate: true :

let output = [];
for(const x of input) {
  output.push(
    {
      id: x.id,
      name: x.name,
      value: x.value,
      date: x.date,
      duplicate: output.some(e => {
        if (e.value === x.value && e.date === x.date) {
          e.duplicate = true;
          return true;
        }
        return false;
      })
    }
  );
}

Edit2: Using filter() and length

let output = [];
for(const x of input) {
  output.push(
    {
      id: x.id,
      name: x.name,
      value: x.value,
      date: x.date,
      duplicate: input.filter(e => e.value === x.value && e.date === x.date).length > 1
    }
  );
}
Related