Образец данных:
[{ '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-код для отображения в таблице:
<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>
Текущий выход:
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
Ожидаемый результат:
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
Пытался:
this.data.forEach(x=>{
console.info('c??',x)
x.Employees.sort((a:any,b:any)=>{ return a.StrtDT- b.StrtDT})})
Здесь я ищу, чтобы отсортировать сначала по флагу, а затем по дате от недавней до старой.
даже хотел бы рассмотреть любой другой подход для получения желаемого результата.
Отсортируйте массив по нескольким полям, сравните флаги, если они совпадают с датами разбора, и сравните их:
Обновление: вам нужно расширить массив сотрудников информацией об отделе. Затем сгладьте массив, чтобы получить массив сотрудников, а затем отсортируйте его.
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.info(arr);
Поскольку вы хотите отсортировать по отделам, вы не можете использовать исходные данные. Получите плоский массив сотрудников со свойством Deprt
.
data.flatMap(({ Deprt, Employees }) =>
Employees.map(emp => ({ ...emp, Deprt, StartDate: getDate(emp.StrtDT) }))
)
Кроме того, вам нужно добавить еще одно свойство под названием StartDate
. Ваш текущий формат не может быть напрямую преобразован в дату. Итак, вам нужно использовать регулярное выражение, чтобы получить каждую часть даты и времени и преобразовать ее в дату
function getDate(dateStr) {
const [d, m, y, h, min] = dateStr.match(/\d+/g)
return new Date(y, m-1, d, h, min)
}
А потом sort
сначала по flag
, а потом по StartDate
array.sort((a, b) => b.flag - a.flag
|| b.StartDate - a.StartDate
)
Вот фрагмент:
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.info(expected)
new Date(a.StrtDT)
вернет неверную дату.
Здравствуйте @adiga, спасибо за вашу помощь, ваш код работает как шарм, просто у меня проблема с датами. Знаете ли вы, почему моя дата меняется, например, с 2023-01-23T17:15
на 1928-07-15T16:15:00.000Z
, не могли бы вы помочь мне с этим? Мне нужна та же дата и формат
@R.Baraiya, это другой формат даты. 2023-01-23T17:15
можно напрямую анализировать без регулярного выражения.
У меня прямая new date(emp.StrtDT)
сработала отлично, еще раз спасибо @adiga
@ R.Baraiya, какой формат даты у вас есть в вашем реальном коде?
у меня такой же формат
@ Р.Барайя 2023-01-23T17:15
или 24-12-2022T08:30
?
Вы правы, с моим фактическим кодом у меня есть yyyymmdd, извините за путаницу.
@ R.Baraiya Тогда у вас нет дополнительной собственности. Просто .sort((a, b) => b.flag - a.flag || new Date(b.StrtDT) - new Date(a.StrtDT))
Хорошее решение @adiga, у меня есть вопрос, что, если нам нужно показать разные сокращения для обоих флагов «нет / выкл», например, для флага со старой на будущую дату и для флага с будущей на старую дату?
@user20042770 user20042770, тогда вам нужно выполнить вторую сортировку условно: .sort((a, b) => b.flag - a.flag || ( a.flag ? a.StartDate - b.StartDate : b.StartDate - a.StartDate) )
Это по-прежнему сортируется внутри отдела. Они хотят показать данные по отделам на основе этих двух полей. ЕСЛИ вы видите их ожидаемый результат, значит, есть 2
IT
сверху и один посередине.