Data Sample:
[{ 'ID': objectID(dcdj12),
'Deprt': 'IT',
'Employees': [ { 'ID': 3, 'StrtDT': '24-12-2022T08:30', 'flag': true },
{ 'ID': 2, 'StrtDT': '14-11-2021T08:30' 'flag': true },
{ 'ID': 1, 'StrtDT': '22-11-2020T08:30', 'flag': false }]
},
{ 'ID': objectID(dcdj132),
'Deprt': 'HR',
'Employees': [ { 'ID': 33, 'StrtDT': '24-12-2022T08:30', 'flag': false},
{ 'ID': 22, 'StrtDT': '14-11-2021T08:30' 'flag': true },
{ 'ID': 11, 'StrtDT': '22-11-2020T08:30', 'flag': false }]
},
{ 'ID': objectID(dcdj1321),'Deprt' : 'AC', 'Employees': []}... more thn 1000 ]
HTML code to show in table:
<tbody>
<ng-container *ngFor="let D of Deprt">
<tr *ngFor="let Emp of D.Employees" >
<td> {{D.Deprt}} </td>
<td> {{Emp.ID}} </td>
<td> {{Emp.StrtDT}} </td>
<td> {{Emp.flag}} </td>
</tr>
</ng-container>
</tbody>
Current Output:
Deprt ID StrtDT flag
IT 3 24-12-2022T08:30 true
IT 2 14-11-2021T08:30 true
IT 1 22-11-2020T08:30 false
HR 33 24-12-2022T08:30 false
HR 22 14-11-2021T08:30 true
HR 11 22-11-2020T08:30 false
Expected Output:
Deprt ID StrtDT flag
IT 3 24-12-2022T08:30 true
IT 2 14-11-2021T08:30 true
HR 22 14-11-2021T08:30 true
HR 33 24-12-2022T08:30 false
IT 1 22-11-2020T08:30 false
HR 11 22-11-2020T08:30 false
Tried:
this.data.forEach(x=>{
console.log('c??',x)
x.Employees.sort((a:any,b:any)=>{ return a.StrtDT- b.StrtDT})})
Here I am looking for to sort first by flag and then by dates recent to old.
even, would like to consider any different approach to get desire output.
CodePudding user response:
Since you want to sort across departments, you can't use the original data. Get a flat array of employees with a Deprt
property.
data.flatMap(({ Deprt, Employees }) =>
Employees.map(emp => ({ ...emp, Deprt, StartDate: getDate(emp.StrtDT) }))
)
Also, you need to add another property called StartDate
. Your current format cannot be converted to a Date directly. So, you need to use regex to get each date time parts and convert it to Date
function getDate(dateStr) {
const [d, m, y, h, min] = dateStr.match(/\d /g)
return new Date(y, m-1, d, h, min)
}
And then sort
firstly based on the flag
and then by StartDate
array.sort((a, b) => b.flag - a.flag
|| b.StartDate - a.StartDate
)
Here's a snippet:
const data = [
{
Deprt: 'IT',
Employees: [
{ ID: 3, StrtDT: '24-12-2022T08:30', flag: true },
{ ID: 2, StrtDT: '14-11-2021T08:30', flag: true },
{ ID: 1, StrtDT: '22-11-2020T08:30', flag: false },
],
},
{
Deprt: 'HR',
Employees: [
{ ID: 33, StrtDT: '24-12-2022T08:30', flag: false },
{ ID: 22, StrtDT: '14-11-2021T08:30', flag: true },
{ ID: 11, StrtDT: '22-11-2020T08:30', flag: false },
],
},
];
function getDate(dateStr) {
const [d, m, y, h, min] = dateStr.match(/\d /g)
return new Date(y, m-1, d, h, min)
}
const expected =
data.flatMap(({ Deprt, Employees}) =>
Employees.map(emp => ({ ...emp, Deprt, StartDate: getDate(emp.StrtDT) }))
)
.sort((a, b) => b.flag - a.flag
|| b.StartDate - a.StartDate
)
console.log(expected)
CodePudding user response:
Sort array by multiple fields, compare flags, if they are the same parse dates and compare them:
Update: you need to extend emloyees array with department info. Then flatten array to get array of employees and then sort it.
let arr = [{ 'Deprt': 'IT',
'Employees': [ { 'ID': 3, 'StrtDT': '24-12-2022T08:30', 'flag': true },
{ 'ID': 2, 'StrtDT': '14-11-2021T08:30' , 'flag': true },
{ 'ID': 1, 'StrtDT': '22-11-2020T08:30', 'flag': false }]
},
{ 'Deprt': 'HR',
'Employees': [ { 'ID': 33, 'StrtDT': '24-12-2022T08:30', 'flag': false},
{ 'ID': 22, 'StrtDT': '14-11-2021T08:30', 'flag': true },
{ 'ID': 11, 'StrtDT': '22-11-2020T08:30', 'flag': false }]
},
{ 'Deprt' : 'AC', 'Employees': []} ];
arr.forEach(o => o.Employees.forEach(e => e.Deprt = o.Deprt));
arr = arr.flatMap(o => o.Employees);
arr.sort( (a,b) => {
if(a.flag !== b.flag) {
return a.flag ? -1 : 1;
} else {
let [d,mon,y,h,min] = a.StrtDT.split(/\D/);
const d1 = new Date(y, mon-1, d, h, min);
[d,mon,y,h,min] = b.StrtDT.split(/\D/);
const d2 = new Date(y, mon-1, d, h, min);
return d2-d1;
}
} );
console.log(arr);