I have an array of objects like below,
[
{
id: 1,
holiday_for: 1,
holiday_on: "2021-10-26"
},
{
id: 2,
holiday_for: 3,
holiday_on: "2021-10-26"
},
{
id: 3,
holiday_for: 1,
holiday_on: "2021-11-26"
},
{
id: 4,
holiday_for: 3,
holiday_on: "2021-11-26"
},
{
id: 5,
holiday_for: 4,
holiday_on: "2021-11-26"
}
]
where the objects have the same dates but different holiday_for. holiday_for has 3 types 1, 3, 4. I am trying to find an object with the same dates which has max holiday_for.
If the array has 2 objects with the same dates and types 1 and 3 then 3 will get high priority. If it has 3 objects with the same dates with types 1, 3, 4 then 4 will get priority.
I have tried using reduce but it returns only the object with the highest type -
const filtered = holidays.reduce((max, cur) =>
max.holiday_for > cur.holiday_for ? max : cur
)
Output type
[
{
id: 2,
holiday_for: 3,
holiday_on: "2021-10-26"
},
{
id: 5,
holiday_for: 4,
holiday_on: "2021-11-26"
}
]
holidays_sorted = holidays.sort((a,b)=>{
if(a.holiday_on === b.holiday_on){
return b.holiday_for - a.holiday_for
}
})
let unique = {};
holidays_sorted = holidays.filter(holiday=> {
if (unique[holiday.holiday_on]) {
return false;
}
unique[holiday.holiday_on] = true;
return true;
});
//keep first unique holiday_on for each date Which is the higher
{id: 2, holiday_for: 3, holiday_on: '2021-10-26'}//<--this
{id: 1, holiday_for: 1, holiday_on: '2021-10-26'}
{id: 5, holiday_for: 4, holiday_on: '2021-11-26'}//<--that
{id: 4, holiday_for: 3, holiday_on: '2021-11-26'}
{id: 3, holiday_for: 1, holiday_on: '2021-11-26'}
Result:
{id: 2, holiday_for: 3, holiday_on: '2021-10-26'}
{id: 5, holiday_for: 4, holiday_on: '2021-11-26'}
As I am using Angular needed to add some types. Based on @Mehdi Taher answer I have added some typing and ended up like this -
const sortedHolidays = holidays.sort(
(a: IHoliday, b: IHoliday) => {
return a.holiday_on === b.holiday_on
? b.holiday_for - a.holiday_for
: 0;
}
);
let unique: { [key: string]: IHoliday | boolean } = {};
const filtered = duplicateHolidays.filter(
(holiday: IHoliday) => {
if (unique[holiday.holiday_on]) {
return false;
}
unique[holiday.holiday_on] = true;
return true;
}
);
If I understand correctly, something like the below.
let ordered = array
.filter(a => a.holiday_on == "2021-11-26")
.sort((a, b) => b.holiday_for - a.holiday_for);
let priority = ordered[0].holiday_for;
ordered.filter(a => a.holiday_for == priority);