Home > Back-end >  get the first of duplicates in array of objects javascript
get the first of duplicates in array of objects javascript

Time:06-29

I have the following data structure that i receive from the api:

[
  {
    id: '10000844',
    text_id: '10000844-01',
  },
  {
    id: '10000844',
    text_id: '10000844-02',
  },
  {
    id: '12000844',
    text_id: '12000844-03',
  },
  {
    id: '12000844',
    text_id: '12000844-07',
  },
  {
    id: '12000814',
    text_id: '12000844-07',
  },
 {
    id: '12002812',
    text_id: '12000844-07',
  },
   {
    id: '12000814',
    text_id: '12000844-08',
  },
]

The perfect outcome of cleaning the code would be this result, basically returning only the first found id:

[
      {
        id: '10000844',
        text_id: '10000844-01',
      },
      {
        id: '12000844',
        text_id: '12000844-03',
      },
      {
        id: '12000814',
        text_id: '12000844-07',
      },
     {
        id: '12002812',
        text_id: '12000844-07',
      },
    ]

But currently it only returns the last found duplicate in a unique array, with the current code:

let uniqueArray = [...new Map(data.map(item =>
    [item.id, item])).values()];

CodePudding user response:

You can use Object.values() and reduce() same as :

const data = [
  {
    id: '10000844',
    text_id: '10000844-01',
  },
  {
    id: '10000844',
    text_id: '10000844-02',
  },
  {
    id: '12000844',
    text_id: '12000844-03',
  },
  {
    id: '12000844',
    text_id: '12000844-07',
  },
  {
    id: '12000814',
    text_id: '12000844-07',
  },
 {
    id: '12002812',
    text_id: '12000844-07',
  },
   {
    id: '12000814',
    text_id: '12000844-08',
  },
]

const result = Object.values(
  data.reduce((res, {id, text_id}) => {
    res[id] ??= {id, text_id}
    return res
  }, {})
)
console.log(result)

CodePudding user response:

You can do it like this:

const arr = [
  {
    id: '10000844',
    text_id: '10000844-01',
  },
  {
    id: '10000844',
    text_id: '10000844-02',
  },
  {
    id: '12000844',
    text_id: '12000844-03',
  },
  {
    id: '12000844',
    text_id: '12000844-07',
  },
  {
    id: '12000814',
    text_id: '12000844-07',
  },
 {
    id: '12002812',
    text_id: '12000844-07',
  },
   {
    id: '12000814',
    text_id: '12000844-08',
  },
];
const unique = [];
const visited = new Set();
for(let i = 0; i < arr.length;   i){
  if(!visited.has(arr[i].id)){
    unique.push(arr[i]);
    visited.add(arr[i].id);
  }
}

console.log(unique);

CodePudding user response:

Concept

Loop through all the objects in the data and check if the id is found in result array. If not found then push it into the result array; otherwise, skip it.

Code

const data = [{
    id: '10000844',
    text_id: '10000844-01',
  },
  {
    id: '10000844',
    text_id: '10000844-02',
  },
  {
    id: '12000844',
    text_id: '12000844-03',
  },
  {
    id: '12000844',
    text_id: '12000844-07',
  },
  {
    id: '12000814',
    text_id: '12000844-07',
  },
  {
    id: '12002812',
    text_id: '12000844-07',
  },
  {
    id: '12000814',
    text_id: '12000844-08',
  },
];
let result = [];
let found;
data.forEach(d => {
  found = false;
  result.forEach(r => {
    if (!found && r.id === d.id) found = true;
  })
  if (!found) result.push(d);
});
console.log(result);

CodePudding user response:

Here is another way to achieve you desire output.
we use reduce for changing in data and use find function to get current id is already in prev or not if not then we use filter function to filter out same id object and push only first.

const data =[
  {
    id: '10000844',
    text_id: '10000844-01',
  },
  {
    id: '10000844',
    text_id: '10000844-02',
  },
  {
    id: '12000844',
    text_id: '12000844-03',
  },
  {
    id: '12000844',
    text_id: '12000844-07',
  },
  {
    id: '12000814',
    text_id: '12000844-07',
  },
 {
    id: '12002812',
    text_id: '12000844-07',
  },
   {
    id: '12000814',
    text_id: '12000844-08',
  },
]

const newData = data.reduce((prev, curr, index, arr) => {
  const find = prev.find(p => p.id === curr.id);
  if (!find) {
    const filter = arr.filter(f => f.id === curr.id);
    if (filter.length >= 1) {
      prev.push(filter[0])
    }
  }
  return prev;
}, [])

console.log(newData)

CodePudding user response:

You can reduce the array into an object that stores only the first occurrence of every id and then extract the values from this object.

const 
  data = [{ id: "10000844", text_id: "10000844-01" }, { id: "10000844", text_id: "10000844-02" }, { id: "12000844", text_id: "12000844-03" }, { id: "12000844", text_id: "12000844-07" }, { id: "12000814", text_id: "12000844-07" }, { id: "12002812", text_id: "12000844-07" }, { id: "12000814", text_id: "12000844-08" }],
  result = Object.values(data.reduce((acc, d) => (!acc[d.id] ? { ...acc, [d.id]: d } : acc), {}));

console.log(result);

CodePudding user response:

Some of the answers are already correct.

THIS ANSWER IS ONLY IF YOU ARE USING LODASH

You can use uniqBy.

This will return a duplicate-free version of an array where the first occurrence is the one that will be kept:

So in your case, something like

import uniqBy from 'lodash/uniqBy';

// dataFromAPI is your sample data
const unqiueArray = uniqBy(dataFromAPI, 'id');
  • Related