Home > other >  Remove duplicates by date in typescript
Remove duplicates by date in typescript

Time:06-10

I have a list of objects order by date. Each object have the folling structure

export class SegmentDTO  {
  dateInsert: Date;
  dateModified: Date;
  id: number;
  language: number;
  content: string;
}

I want to get the disctincs object based on language property, and take the most recent one of each language (based on dateModified)

What I tried is this:

const listLangOrderByDateASC = this.segments.sort((a, b) => new Date(a.dateInsert).getTime() - new Date(b.dateInsert).getTime());

 const result = [...new Map(listSourceLangOrderByDateASC.map(item => [item.language, item])).values()];

With this, I can obtain the most recent object for each language, but I don't know if there is a better approach to do it. I discover that making this takes the final objects of the sorted list, but I don't really know if it's just lucky.

Any help would be aprecciated!

CodePudding user response:

You could use Array.reduce() to get the most recently modified items, grouped by language.

We'll create an object, with a key for each language. If the object has no value at the language key or the value has an older modified date, we'll replace with the new entry.

Once we've grouped the items, we'll convert to an array again with Object.values()

let segments = [ { dateInsert: new Date('2022-06-01T07:00:00Z'), dateModified: new Date('2022-06-02T09:00:00Z'), id: 1, language: 1, content: 'Content', }, { dateInsert: new Date('2022-06-01T07:00:00Z'), dateModified: new Date('2022-06-02T11:00:00Z'), id: 1, language: 1, content: 'Content', }, { dateInsert: new Date('2022-06-01T07:00:00Z'), dateModified: new Date('2022-06-02T14:00:00Z'), id: 1, language: 2, content: 'Content', }, { dateInsert: new Date('2022-06-01T07:00:00Z'), dateModified: new Date('2022-06-01T19:00:00Z'), id: 1, language: 2, content: 'Content', } ];

const result = Object.values(segments.reduce((acc, obj) => { 
    if (!acc[obj.language] || (acc[obj.language].dateModified < obj.dateModified)) {
        acc[obj.language] = obj;
    }
    return acc;
}, {}));
console.log('Result:', result)
.as-console-wrapper { max-height: 100% !important; }

We can also do this with a Map object:

const segments = [ { dateInsert: new Date('2022-06-01T07:00:00Z'), dateModified: new Date('2022-06-02T09:00:00Z'), id: 1, language: 1, content: 'Content', }, { dateInsert: new Date('2022-06-01T07:00:00Z'), dateModified: new Date('2022-06-02T11:00:00Z'), id: 1, language: 1, content: 'Content', }, { dateInsert: new Date('2022-06-01T07:00:00Z'), dateModified: new Date('2022-06-02T14:00:00Z'), id: 1, language: 2, content: 'Content', }, { dateInsert: new Date('2022-06-01T07:00:00Z'), dateModified: new Date('2022-06-01T19:00:00Z'), id: 1, language: 2, content: 'Content', } ];

const result = [...segments.reduce((acc, obj) => {
    if ((!acc.has(obj.language) || (acc.get(obj.language).dateModified) < obj.dateModified)) {
        acc.set(obj.language, obj);
    }
    return acc;
}, new Map()).values()];
console.log('Result:', result)
.as-console-wrapper { max-height: 100% !important; }

CodePudding user response:

you can try something like this

const segments = [{
 dateInsert: new Date('2022-01-01 00:00:00'),
 dateModified: new Date('2022-01-01 00:00:00'),
 id: 1,
 language: 1,
 content: 'My content'
},{
 dateInsert: new Date('2022-01-01 00:00:00'),
 dateModified: new Date('2022-01-02 00:00:00'),
 id: 2,
 language: 1,
 content: 'My content'
}
]


const mostRecentByLanguage = Object.values(segments.reduce((res, item) => {
  
  const existing =  res[item.language] || {dateModified :new Date('1970-01-01 00:00:00')}

  return {
    ...res,
    [item.language]: item.dateModified.getTime() > existing.dateModified.getTime() ?item:existing
  }

}, {})).flat()

console.log(mostRecentByLanguage)

CodePudding user response:

You can browse all table elements and slice the table from current index 1 until the last element, if you don't find the current element you push it in a new table:

var unique =[]
arr.forEach((e,i,s)=>{
if(s.slice(i 1).filter(c=>c.language==e.language).length==0)
unique.push(e)
})
  • Related