0

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" class="card-text">
       <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.

0

2 Answers 2

3

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)

Sign up to request clarification or add additional context in comments.

11 Comments

new Date(a.StrtDT) will return invalid date.
Hello @adiga thank you for your help, your code is working like charm, just I have issue with dates do you know why my date is getting change like 2023-01-23T17:15 to 1928-07-15T16:15:00.000Z can you please help me with it? I need the same date and format
@R.Baraiya that is a different date format. 2023-01-23T17:15 can directly be parsed to date without the regex.
@R.Baraiya Then you don't the extra property. Just .sort((a, b) => b.flag - a.flag || new Date(b.StrtDT) - new Date(a.StrtDT))
@user20042770 then you have to do the second sorting conditionally: .sort((a, b) => b.flag - a.flag || ( a.flag ? a.StartDate - b.StartDate : b.StartDate - a.StartDate) )
|
1

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);

1 Comment

This still sorts within the department. They want to show the data across departments based on these 2 fields. IF you see their expectedoutput, there are 2 IT on top and one in between.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.