Considering the original data you provided,
const rawData = [
{ "Name": "Jack", "IncomingTime": "2020-06-19T11:02+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", },
{ "Name": "Mary", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", },
{ "Name": "jolly", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", },
{ "Name": "Jack", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", },
{ "Name": "Maria", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:17+00:00", },
{ "Name": "Maria", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T12:53+00:00", },
{ "Name": "Jack", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", }
];
To achieve your desired output, we follow these steps:
Initially, we arrange the raw data based on Name
, then IncomingTime
, and finally by OutgoingTime
.
Next, we loop through the sorted data and keep track of the previous item visited. When a change in the primary sort key (a name difference) is observed, it indicates the desired item (e.g., the record for the specific name with the earliest incoming time), which is then added to the set of unique items. A sequence break occurs when:
- No previous item exists, indicating the first item in the list.
- The Names of the current and previous items are different.
This results in the following solution.
const sortedData = rawData.sort(
(x,y) => x.Name < y.Name ? -1 // sort by name
: x.Name > y.Name ? +1 //
: x.IncomingTime < y.IncomingTime ? -1 // followed by incoming time
: x.IncomingTime > y.IncomingTime ? +1 //
: x.Outgoingtime < y.Outgoingtime ? -1 // and outgoing time
: x.Outgoingtime > y.Outgoingtime ? +1
: 0 // both items compare equal
);
const uniqueData = [];
let prev;
for (const curr of sortedData) {
if ( !prev || curr.Name !== prev.Name ) {
uniqueData.push(curr);
}
prev = curr;
}
console.log(JSON.stringify(uniqueData,undefined,2));
This code snippet outputs:
[
{
"Name": "Jack",
"IncomingTime": "2020-06-19T11:02+00:00",
"Outgoingtime": "2020-06-19T11:07+00:00"
},
{
"Name": "Maria",
"IncomingTime": "2020-06-19T11:05+00:00",
"Outgoingtime": "2020-06-19T11:17+00:00"
},
{
"Name": "Mary",
"IncomingTime": "2020-06-19T11:05+00:00",
"Outgoingtime": "2020-06-19T11:07+00:00"
},
{
"Name": "jolly",
"IncomingTime": "2020-06-19T11:05+00:00",
"Outgoingtime": "2020-06-19T11:07+00:00"
}
]
An alternative approach using Map
can simplify this process while retaining the order of the sorted list:
const sortedData = rawData.sort(
(x,y) => x.Name < y.Name ? -1 // sort by name
: x.Name > y.Name ? +1 //
: x.IncomingTime < y.IncomingTime ? -1 // followed by incoming time
: x.IncomingTime > y.IncomingTime ? +1 //
: x.Outgoingtime < y.Outgoingtime ? -1 // and outgoing time
: x.Outgoingtime > y.Outgoingtime ? +1
: 0
);
const map = new Map();
for (const entry of sortedData) {
const value = map.get(entry.Name);
if (!value) {
map.set(entry.Name, entry);
}
}
const uniqueData = Array.from(map.values());