3

I have an array of objects stored in 'component' variable

component=[{id:1,date:'20-10-2020'},{id:1,date:'13-01-2020'},{id:2,date:'30-03-2020'}]

Here I'm having 2 objects with 'id' as same(id:1) but with different dates. If there are multiple objects with the same id in it, I need to take out only the id with the latest date. Is it possible with filters?

After filtering, I need the output like

component=[{id:1,date:'20-10-2020'},{id:2,date:'30-03-2020'}]

Here '{id:1,date:'13-01-2020'}' is removed from the array.

Thanks in advance

Sahal
  • 105
  • 13

4 Answers4

1

You may do so using the following code which makes use of a Map:

let map = new Map();

component.forEach(e => {
  if (map.get(e.id) !== undefined) {     
    // current date
    const [newDay, newMonth, newYear] = e.date.split("-")
    let newDate = new Date(newYear, newMonth - 1, newDay);
    
    // previous date
    const [oldDay, oldMonth, oldYear] = map.get(e.id).split("-")
    let oldDate = new Date(oldYear, oldMonth - 1, oldDay);
    
    // compare the date and pick the latest
    map.set(e.id, newDate > oldDate ? e.date : map.get(e.id));
  } else {
    map.set(e.id, e.date);
  }
});

// clear the original contents
component = [];

// now populate it from the map
for (let e of map.entries()) {
   component.push({id: e[0], date: e[1]});
}
console.log(component);
Nicholas K
  • 15,148
  • 7
  • 31
  • 57
0

Try the following example please

I must move soon, if I am well I will comment on what I did

const data = [
  { id: 1, date: "20-10-2020" },
  { id: 1, date: "13-01-2020" },
  { id: 2, date: "30-03-2020" },
];

const output = data.reduce((previousValue, currentValue) => {
  const entity = previousValue.find((entry) => entry.id === currentValue.id);

  if (entity !== undefined) {
    const [
      currentValueDate,
      currentValueMonth,
      currentValueYear,
    ] = currentValue.date.split("-");
    const [entityDate, entityMonth, entityYear] = entity.date.split("-");
    const currentValueTimestamp = new Date(
      currentValueYear,
      currentValueMonth - 1,
      currentValueDate
    ).getTime();
    const entityTimestamp = new Date(
      entityYear,
      entityMonth - 1,
      entityDate
    ).getTime();

    const index = previousValue.findIndex(
      (entry) => entry.id === currentValue.id
    );

    if (entityTimestamp > currentValueTimestamp) {
      previousValue[index] = entity;

      return previousValue;
    }
  }

  return [...previousValue, currentValue];
}, []);

console.log(output);

See

Mario
  • 4,784
  • 3
  • 34
  • 50
0

/**
 * Notice that I changed your date input format,
 * because they are invalid as far as javascript Date object is concerned,
 * or you can use momentJS.
 * 
 * If you decide to use moment, then you could just do something like this
 * 
 * moment('your date string goes here').format('DD-MM-YYYY')
 * 
 * More information on date manipulation with moment can be found on their
 * official website.
 * 
 * */
let component=[{id:1,date:'10-20-2020'},{id:1,date:'01-13-2020'},{id:2,date:'03-30-2020'}]

function deDup(listOfObjects: Array<{id: number, [propName: string]: any}>): Array<{id: number, [propName: string]: any}> {
    let res: Array<any> = [],
        groupings: {[propName: number]: Array<any>} = {}; /**propName here will be the attribute of unique identifier, eg id */

    /**First group the similar objects under the same id */
    listOfObjects.forEach(object => {
        if (!groupings[object.id]) groupings[object.id] = [];
        groupings[object.id].push(object)
    })
    
    /**Next order the duplicates based on the date attribute */
    for (let key in groupings) {
        let groupingItems = groupings[key].sort((a: any, b: any) => {
            return new Date(a.date) > new Date(b.date) ? 1 : 0
        });
        /**Now, from each grouping, pick the first one, as it is the latest, based on the sorting */
        res.push(groupingItems[0]);
    }
    return res;
}

let res = deDup(component);

console.log('res', res)
0

const component = [{
  id: 1,
  date: '20-10-2020'
}, {
  id: 1,
  date: '13-01-2020'
}, {
  id: 2,
  date: '30-03-2020'
}];

const byLatestDate = input => {
  const parse = date => {
    const [day, month, year] = date.split("-");
    return new Date(year, month, day);
  };
  return component.filter(({id,date}) =>id === input.id && date !== input.date)
                  .every(({date}) => parse(date) < parse(input.date));
}

console.log(component.filter(byLatestDate));

Hope it works for you.

Shuvojit Saha
  • 382
  • 2
  • 11