У меня есть два отсортированных массива, и я объединил их в новый список C.
listA = [
{id:"1234435", name:"apple", dateTime_ISO:"2019-01-15 17:27:30"},
{id:"1234435", name:"orange", dateTime_ISO:"2019-01-15 10:25:30"},
{id:"1234435", name:"banana", dateTime_ISO:"2019-01-15 10:25:02"},
{id:"1234435", name:"pear", dateTime_ISO:"2019-01-15 07:21:52"},
{id:"1234435", name:"lemon", dateTime_ISO:"2019-01-15 07:22:24"},
]
listB = [
{id:"1234435", name:"bread", dateTime:"2019-01-15 17:27:34"},
{id:"1234435", name:"rice", dateTime:"2019-01-15 09:25:30"},
{id:"1234435", name:"noodle", dateTime:"2019-01-15 07:25:02"},
{id:"1234435", name:"pie", dateTime:"2019-01-15 07:06:52"},
{id:"1234435", name:"cake", dateTime:"2019-01-15 06:22:24"},
]
listC = this.listA.concat(this.listB)
Как отсортировать listC по дате и времени?
Итак, я думал получить новый dateTimeList, содержащий только dateTime, затем отсортировать этот список и как-то отсортировать список
dateTimeList = this.listA
.map(x => x.dateTime_ISO)
.concat(this.listB.map(x => x.dateTime));
Но есть ли надежный способ отсортировать этот dateTimeList?
Если это невозможно сделать только потому, что два списка имеют разные имена полей (dateTime_ISO и dateTime), просто представьте, что они одинаковы. Я мог бы изменить их так, чтобы они были такими же в базе данных.
Благодарю за любую помощь.
@dtanabe спасибо за советы, и я удалю тег angular.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


dateTimeList = this.listA.sort(function(a,b){
//return a.attributes - b.attributes;
if (a.date < b.date)
return 1;
if (a.date > b.date)
return -1;
});
удобный способ сортировки по дате.
Вы можете воспользоваться коротким замыканием, чтобы отсортировать объединенный список, сохраняя при этом разные свойства. Например:
let listA = [{id:"1234435", name:"apple", dateTime_ISO:"2019-01-15 17:27:30"},{id:"1234435", name:"orange", dateTime_ISO:"2019-01-15 10:25:30"},{id:"1234435", name:"banana", dateTime_ISO:"2019-01-15 10:25:02"},{id:"1234435", name:"pear", dateTime_ISO:"2019-01-15 07:21:52"},{id:"1234435", name:"lemon", dateTime_ISO:"2019-01-15 07:22:24"},]
let listB = [{id:"1234435", name:"bread", dateTime:"2019-01-15 17:27:34"},{id:"1234435", name:"rice", dateTime:"2019-01-15 09:25:30"},{id:"1234435", name:"noodle", dateTime:"2019-01-15 07:25:02"},{id:"1234435", name:"pie", dateTime:"2019-01-15 07:06:52"},{id:"1234435", name:"cake", dateTime:"2019-01-15 06:22:24"},]
let listC = listA.concat(listB)
listC.sort((a, b) => {
return (a.dateTime_ISO || a.dateTime).localeCompare((b.dateTime_ISO || b.dateTime))
})
console.info(listC)Большое спасибо за решение. Итак, если я хочу, чтобы все было в обратном порядке, что мне нужно применить?
@Alex, чтобы отменить его, вы можете поменять местами a и b: listC.sort((b, a)
Вы можете использовать sort(), а в условии сортировки проверить, существует ли какое-либо свойство (пример: dateTime_ISO), и, если нет, использовать альтернативное имя свойства (dateTime):
const listA = [
{id:"1234435", name:"apple", dateTime_ISO:"2019-01-15 17:27:30"},
{id:"1234435", name:"orange", dateTime_ISO:"2019-01-15 10:25:30"},
{id:"1234435", name:"banana", dateTime_ISO:"2019-01-15 10:25:02"},
{id:"1234435", name:"pear", dateTime_ISO:"2019-01-15 07:21:52"},
{id:"1234435", name:"lemon", dateTime_ISO:"2019-01-15 07:22:24"},
]
const listB = [
{id:"1234435", name:"bread", dateTime:"2019-01-15 17:27:34"},
{id:"1234435", name:"rice", dateTime:"2019-01-15 09:25:30"},
{id:"1234435", name:"noodle", dateTime:"2019-01-15 07:25:02"},
{id:"1234435", name:"pie", dateTime:"2019-01-15 07:06:52"},
{id:"1234435", name:"cake", dateTime:"2019-01-15 06:22:24"},
]
let listC = listA.concat(listB);
// Now, lets sort.
let sortedListC = listC.sort((a, b) =>
{
let x = (a.dateTime_ISO || a.dateTime);
let y = (b.dateTime_ISO || b.dateTime);
return ((x > y) && 1) || ((x < y) && -1) || 0;
});
console.info(sortedListC);Использование одного теста > при сортировке некорректно и может привести к неправильным сортировкам. sort ожидает, что функция вернет -1, 1 или 0 неверно или неверно. Попробуйте добавить элемент с таким же временем.
Я уловил то, что вы говорите, но я попытался создать проблему, но не могу. Есть идеи, почему все еще работает?
Я думаю, что часто будет работать, если будут возвращены только 1 и 0, но это зависит от исходного порядка. Здесь старая угроза: stackoverflow.com/questions/34466125/…
@MarkMeyer благодарит за отзыв и помощь в понимании неявной проблемы, я обновился до более надежного решения.
Поскольку listA и listB уже отсортированы в порядке убывания, я думаю, вы можете использовать этот факт и объединить их. Это должно быть O (n) - вместо (nlog (n)), если вы сортируете результат после конкатенации.
Попробуйте что-то вроде этого
var listA = [
{id:"1234435", name:"apple", dateTime_ISO:"2019-01-15 17:27:30"},
{id:"1234435", name:"orange", dateTime_ISO:"2019-01-15 10:25:30"},
{id:"1234435", name:"banana", dateTime_ISO:"2019-01-15 10:25:02"},
{id:"1234435", name:"pear", dateTime_ISO:"2019-01-15 07:21:52"},
{id:"1234435", name:"lemon", dateTime_ISO:"2019-01-15 07:22:24"},
];
var listB = [
{id:"1234435", name:"bread", dateTime:"2019-01-15 17:27:34"},
{id:"1234435", name:"rice", dateTime:"2019-01-15 09:25:30"},
{id:"1234435", name:"noodle", dateTime:"2019-01-15 07:25:02"},
{id:"1234435", name:"pie", dateTime:"2019-01-15 07:06:52"},
{id:"1234435", name:"cake", dateTime:"2019-01-15 06:22:24"},
];
function merge(a, b) {
var ret = [];
while (a.length && b.length) {
var smallest = a[0].dateTime_ISO > b[0].dateTime ? a.shift() : b.shift();
ret.push(smallest);
}
return ret.concat(a.length ? a : b);
};
console.info(JSON.stringify(merge(listA, listB), null, 2));
Возможный дубликат stackoverflow.com/questions/6567941/…; также этот вопрос вообще не кажется специфичным для Angular, поэтому название немного вводит в заблуждение.