How can I filler the below array on common id
and output should have unique and latest history number
const input = [{
"id": 134116,
"user": "admin",
"historyno": "134116-0"
}, {
"id": 134132,
"user": "admin",
"historyno": "134132-0"
}, {
"id": 134132,
"user": "admin",
"historyno": "134132-1"
}, {
"id": 134133,
"user": "admin",
"historyno": "134133-0"
}, {
"id": 134133,
"user": "admin",
"historyno": "134133-1"
}];
let output = [];
let tempId;
for (let i = 0; i < input.length; i++) {
if (input[i].id === tempId) {
//do nothing
} else {
output.push(input[i]);
tempId = input[i].id;
}
}
console.log(output);
Expected Output
[
{
"id": 134116,
"user": "admin",
"historyno": "134116-0"
},
{
"id": 134132,
"user": "admin",
"historyno": "134132-1"
},
{
"id": 134133,
"user": "admin",
"historyno": "134133-1"
}
]
Reduce the array to a Map, using the id
as key, and then convert back by spreading the Map.values()
iterator to an array.
This solution assumes that the array is presorted by history numbers:
const input = [{"id":134116,"user":"admin","historyno":"134116-0"},{"id":134132,"user":"admin","historyno":"134132-0"},{"id":134132,"user":"admin","historyno":"134132-1"},{"id":134133,"user":"admin","historyno":"134133-0"},{"id":134133,"user":"admin","historyno":"134133-1"}];
const output = [...input.reduce((r, o) => r.set(o.id, o), new Map).values()];
console.log(output);
This solution handles unsorted arrays by only replacing the current item in the map if historyno
is greater:
const input = [{"id":134116,"user":"admin","historyno":"134116-0"},{"id":134132,"user":"admin","historyno":"134132-0"},{"id":134132,"user":"admin","historyno":"134132-1"},{"id":134133,"user":"admin","historyno":"134133-0"},{"id":134133,"user":"admin","historyno":"134133-1"}];
const getHistoryNo = ({ historyno }) => +historyno.split('-')[1];
const output = [...input.reduce((r, o) => {
const prev = r.get(o.id);
if(!prev || getHistoryNo(o) > getHistoryNo(prev)) r.set(o.id, o);
return r;
}, new Map).values()];
console.log(output);