Переупорядочить массив на основе значений - PullRequest
0 голосов
/ 04 марта 2020

У меня есть массив с классами (класс называется Note), и в этих классах есть базовые c значения. Двумя важными значениями являются Note.Pinned (логическое значение, закреплено оно или нет) и Note.Modified (отметка времени, когда оно было отредактировано в последний раз).

Я бы хотел отсортировать этот массив классов по Modified отметка времени, затем измените порядок, чтобы заметки Pinned были в верхней части этого списка.

Я уже пытался отсортировать заметки.

const SortedNotes = Notes.sort((a, b) => a.Modified > b.Modified);

Notes - массив с классами.

Но тогда есть ли лучший способ перегруппировать этот массив? Или это единственный метод, который я могу использовать?

SortedNotes.filter(n => n.Pinned).concat(SortedNotes.filter(n => !n.Pinned));

Сказанное выше сработает, и я знаю, что могу использовать Array.prototype.partition, так есть ли другой способ сделать это?

Спасибо

Ответы [ 5 ]

2 голосов
/ 04 марта 2020

Вы можете просто добавить закрепленное требование сортировки к сортировке:

const arr = [{
    pinned: false,
    modified: 7
  },
  {
    pinned: false,
    modified: 6
  },
  {
    pinned: true,
    modified: 2
  },
  {
    pinned: false,
    modified: 4
  },
  {
    pinned: true,
    modified: 1
  },
  {
    pinned: true,
    modified: 8
  },
  {
    pinned: false,
    modified: 3
  },
]

arr.sort((a, b) => {
  if (a.pinned != b.pinned)
    return a.pinned ? -1 : 1;
  return b.modified - a.modified;
})

console.log(arr)

Пока выполнение функции сортировки возвращает одинаковый результат для тех же двух заданных параметров, сортировка будет работать нормально. Зная это, вы можете обрабатывать два состояния, в которых закрепленное состояние отличается, а затем сортировать по измененным, только если закрепленное состояние одинаково.

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

Вы можете сортировать по нескольким условиям:

const SortedNotes = Notes.sort((a, b) => {
  if (a.Pinned == b.Pinned) {
    if (a.Modified > b.Modified) return -1;
    if (a.Modified < b.Modified) return 1;
  } else {
    return a.Pinned ? -1 : 1;
  }
});

Отсутствующая ветвь a.Pinned == b.Pinned && a.Modified == b.Modified вернет undefined, что, в свою очередь, будет интерпретировано как равное.

Кстати, сам массив Notes был бы изменен на месте, поэтому и SortedNotes, и Notes имели бы одинаковый порядок; Конечно, присвоение переменной const не повредит.

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

Возможно, не лучшее решение, но оно должно помочь вам в правильном направлении. Это сортирует массив так, что заметки располагаются в порядке убывания даты с закрепленными вверху.

В отличие от других (лучших) ответов, это имеет сложность сортировки O (2n), так что имейте это в виду.

const notes = [
  {
    text: "foo",
    modified: 1583337610387,
    pinned: false
  },
  {
    text: "bar",
    modified: 1583337610388,
    pinned: true
  },
  {
    text: "baz",
    modified: 1583337610389,
    pinned: false
  },
  {
    text: "qux",
    modified: 1583337610390,
    pinned: true
  }
];

const sortedNotes = [...notes];
sortedNotes.sort((a, b) => a.modified > b.modified ? -1 : 1);
sortedNotes.sort((a, b) => (a.pinned === b.pinned) ? 0 : a.pinned ? -1 : 1);
console.log(sortedNotes);
0 голосов
/ 04 марта 2020

Я отредактировал ответ @ Ja͢ck, чтобы он был немного более компактным.

const SortedNotes = Notes.sort((a, b) => {
    if (a.Pinned == b.Pinned) return a.Modified > b.Modified ? -1 : 1;
    else return a.Pinned ? -1 : 1;
});
0 голосов
/ 04 марта 2020

Короче, можете попробовать

const SortedNotes = Notes.sort((a, b) => {
    if (a.Pinned > b.Pinned)
       return 1;
    if (a.Pinned == b.Pinned) 
       return a.Modified > b.Modified;
    return -1;
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...