Tengo una lista de objetos ordenados por fecha. Cada objeto tiene la siguiente estructura
export class SegmentDTO { dateInsert: Date; dateModified: Date; id: number; language: number; content: string; } Quiero obtener el objeto disctincs según la propiedad del language y tomar el más reciente de cada idioma (basado en dateModified )
Lo que probé es esto:
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()];Con esto, puedo obtener el objeto más reciente para cada idioma, pero no sé si hay un mejor enfoque para hacerlo. Descubro que hacer esto toma los objetos finales de la lista ordenada, pero realmente no sé si es solo suerte.
¡Cualquier ayuda sería apreciada!
Puede usar Array.reduce() para obtener los elementos modificados más recientemente, agrupados por idioma.
Crearemos un objeto, con una clave para cada idioma. Si el objeto no tiene valor en la clave de idioma o el valor tiene una fecha de modificación anterior, lo reemplazaremos con la nueva entrada.
Una vez que hayamos agrupado los elementos, volveremos a convertirlos en una matriz con 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; } También podemos hacer esto con un objeto Map :
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; }puedes intentar algo como esto
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)Puede explorar todos los elementos de la tabla y dividir la tabla desde el índice actual + 1 hasta el último elemento, si no encuentra el elemento actual, lo inserta en una nueva tabla:
var unique =[] arr.forEach((e,i,s)=>{ if(s.slice(i+1).filter(c=>c.language==e.language).length==0) unique.push(e) })