Сортировка массива объектов по нескольким критериям с неопределенными значениями - PullRequest
0 голосов
/ 24 марта 2020

Я пытаюсь отсортировать следующий массив объектов в порядке des c.

const data = [
  {
    scheduledTime: '22:00',
    arrivalTime: '22:12',
  },
  {
    scheduledTime: '20:10',
    arrivalTime: undefined,
  },
  {
    scheduledTime: '08:55',
    arrivalTime: '23:12',
  },
  {
    scheduledTime: '08:55',
    arrivalTime: undefined,
  },
  {
    scheduledTime: '09:55',
    arrivalTime: undefined,
  },
];

Правила таковы: сначала сортировка по прибытию, а затем по запланированному времени. Все неопределенные значения параметра «ivalTime »должны находиться в конце массива. Как только все неопределенные значения из «Arrival» находятся в конце массива, он должен быть снова отсортирован по «запланированному времени» в des c.

Вот что у меня есть в настоящее время:

const multiSort = data.sort(function(a, b) {
  if (a.arrivalTime === undefined) return 1;
  if (b.arrivalTime === undefined) return -1;
  if (a.arrivalTime === b.arrivalTime) return 0;

  if (a.arrivalTime > b.arrivalTime) return -1;
  if (a.arrivalTime < b.arrivalTime) return 1;

  return a.scheduledTime < b.scheduledTime ? 1 : -1;
});

Что такое вывод:

  0: {scheduledTime: "08:55", arrivalTime: "23:12"}
  1: {scheduledTime: "22:00", arrivalTime: "22:12"}
  2: {scheduledTime: "20:10", arrivalTime: undefined} //scheduledTime not in desc
  3: {scheduledTime: "08:55", arrivalTime: undefined} //scheduledTime not in desc
  4: {scheduledTime: "09:55", arrivalTime: undefined} //scheduledTime not in desc

Желание вывода:

  0: {scheduledTime: "08:55", arrivalTime: "23:12"}
  1: {scheduledTime: "22:00", arrivalTime: "22:12"}
  2: {scheduledTime: "20:10", arrivalTime: undefined} //scheduledTime in desc
  3: {scheduledTime: "09:55", arrivalTime: undefined} //scheduledTime in desc
  4: {scheduledTime: "08:55", arrivalTime: undefined} //scheduledTime in desc

Заранее спасибо :)

Ответы [ 6 ]

1 голос
/ 24 марта 2020

Попробуйте проверить и a.arrivalTime, и b.arrivalTime: undefined

const data = [{
    scheduledTime: '22:00',
    arrivalTime: '22:12',
  },
  {
    scheduledTime: '20:10',
    arrivalTime: undefined,
  },
  {
    scheduledTime: '08:55',
    arrivalTime: '23:12',
  },
  {
    scheduledTime: '08:55',
    arrivalTime: undefined,
  },
  {
    scheduledTime: '09:55',
    arrivalTime: undefined,
  },
];

const multiSort = data.sort(function(a, b) {
  if (a.arrivalTime === undefined && b.arrivalTime === undefined) {
    return a.scheduledTime < b.scheduledTime ? 1 : -1;
  }
  if (a.arrivalTime === undefined) return 1;
  if (b.arrivalTime === undefined) return -1;
  return a.arrivalTime < b.arrivalTime ? 1 : -1;
});

console.log(multiSort)
1 голос
/ 24 марта 2020

Я думаю, что это решит вашу проблему:

  const multiSort = data.sort(function(a, b) {
    if (a.arrivalTime === undefined){
        if(b.arrivalTime === undefined) {
            return a.scheduledTime < b.scheduledTime ? 1 : -1;
        } else {
            return 1;
        }
    }
    if (b.arrivalTime === undefined) { // At this point a.arrivalTime cannot be undefined
        return -1;
    }
    if (a.arrivalTime === b.arrivalTime) {
        return a.scheduledTime < b.scheduledTime ? 1 : -1;
    }

    if (a.arrivalTime > b.arrivalTime) return -1;
    if (a.arrivalTime < b.arrivalTime) return 1;
  });

Попробуйте и дайте мне знать, у вас должно быть больше тестов, чтобы убедиться.

0 голосов
/ 24 марта 2020

Давайте посмотрим, что происходит в вашем коде, если мы сравним следующие два объекта:

const firstTime = {
  scheduledTime: '20:10',
  arrivalTime: undefined,
}

const secondTime = {
  scheduledTime: '09:55',
  arrivalTime: undefined,
}

sort(firstTime, secondTime)

function sort (a, b) {
  if (a.arrivalTime === undefined) return 1; // this returns 1 already, since firstTime.arrivalTime === undefined. The rest of your code is never executed
  if (b.arrivalTime === undefined) return -1;
  if (a.arrivalTime === b.arrivalTime) return 0;

  if (a.arrivalTime > b.arrivalTime) return -1;
  if (a.arrivalTime < b.arrivalTime) return 1;

  return a.scheduledTime < b.scheduledTime ? 1 : -1;
}

Чтобы изменить это, вам нужно вложить свои циклы. Я создал рабочий пример на CodePen: https://codepen.io/mewitte-the-flexboxer/pen/dyogGQx

0 голосов
/ 24 марта 2020

Если arrivalTimes равно, проверьте scheduleTime для сортировки.

Используйте '0', когда значения undefined, чтобы переместить их в конец.

const data = [{ scheduledTime: '22:00', arrivalTime: '22:12', },{scheduledTime: '21:00',arrivalTime: '22:12'}, { scheduledTime: '20:10', arrivalTime: undefined, }, { scheduledTime: '08:55', arrivalTime: '23:12', }, { scheduledTime: '08:55', arrivalTime: undefined, }, { scheduledTime: '09:55', arrivalTime: undefined, }, ];

data.sort((a, b) => {
  return (b.arrivalTime || '0').replace(':', '') - (a.arrivalTime || '0').replace(':', '') ||
    (b.scheduledTime || '0').replace(':', '') - (a.scheduledTime || '0').replace(':', '')
});

console.log(data)
0 голосов
/ 24 марта 2020

Используя базовое преобразование c, я получаю в итоге это решение.

const data = [{ scheduledTime: '22:00', arrivalTime: '22:12', }, { scheduledTime: '20:10', arrivalTime: undefined, }, { scheduledTime: '08:55', arrivalTime: '23:12', }, { scheduledTime: '08:55', arrivalTime: undefined, }, { scheduledTime: '09:55', arrivalTime: undefined, }, ];
const date = str => {
  if (!str) return 0;
  const [h, m] = str.split(":");
  return Number(h) * 60 + Number(m);
};
const dateDiff = (t1, t2) => date(t2) - date(t1);
const sortByArvAndSchDate = (
  { arrivalTime: aa, scheduledTime: aas },
  { arrivalTime: ba, scheduledTime: bas }
) => {
  const diff = dateDiff(aa, ba);
  return diff !== 0 ? diff : dateDiff(aas, bas);
};
const result = data.sort(sortByArvAndSchDate);
console.log(result);
0 голосов
/ 24 марта 2020

вы можете использовать loda sh sortBy для этого.

_.sortBy(array, ['key1', 'key2'])

ссылка на loda sh

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...