Объедините два массива и отсортируйте их по полю dateTime

У меня есть два отсортированных массива, и я объединил их в новый список 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), просто представьте, что они одинаковы. Я мог бы изменить их так, чтобы они были такими же в базе данных.

Благодарю за любую помощь.

Возможный дубликат stackoverflow.com/questions/6567941/…; также этот вопрос вообще не кажется специфичным для Angular, поэтому название немного вводит в заблуждение.

dtanabe 15.01.2019 05:28

@dtanabe спасибо за советы, и я удалю тег angular.

Alex 15.01.2019 05:33
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
2
897
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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 15.01.2019 05:51

@Alex, чтобы отменить его, вы можете поменять местами a и b: listC.sort((b, a)

Mark 15.01.2019 05:53

Вы можете использовать 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 неверно или неверно. Попробуйте добавить элемент с таким же временем.

Mark 15.01.2019 06:05

Я уловил то, что вы говорите, но я попытался создать проблему, но не могу. Есть идеи, почему все еще работает?

Shidersz 15.01.2019 06:19

Я думаю, что часто будет работать, если будут возвращены только 1 и 0, но это зависит от исходного порядка. Здесь старая угроза: stackoverflow.com/questions/34466125/…

Mark 15.01.2019 08:45

@MarkMeyer благодарит за отзыв и помощь в понимании неявной проблемы, я обновился до более надежного решения.

Shidersz 15.01.2019 15:47

Поскольку 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));

Другие вопросы по теме