Как отсортировать массив объектов и по свойству и по имени одновременно, не создавая новых объектов?

Дано: Список объектов, содержащий разные свойства, пример объекта:

  {
    type: 'point',
    name: 'abc',
  }

Мне нужно отсортировать все объекты так, чтобы сначала были с типом point по алфавиту, а потом все остальные, тоже по алфавиту. Должно получится примерно следующее:

{
  type: 'point',
  name: 'abc',
},{
  type: 'point',
  name: 'bcd',
}, {
  type: 'other',
  name: 'abc',
}, {
  type: 'other',
  name: 'def'
}

Как сортировать по имени\признаку отдельно - мне понятно. Задачу можно решить созданием 2 новых списков, в первый войдут все по типу и сортируются по алфавиту, вторые все остальные, которые тоже сортируются по алфавиту. А затем склеить эти два списка.

Но можно ли сделать это в одной функции сортировки? Или хотя бы за два прогона, но без создания+склеивания новых массивов.

На данный момент проблема частично решается так:

list.sort( (a,b) => {
 if (a.name < b.name) return -1;
 if (a.name > b.name) return 1;
 return 0;
});

list.sort( (a,b) => {
 if (a.type === 'point') return -1;
 if (b.type === 'point && a.type !== 'point) return 0;
 return 1;
});

Таким образом, список объектов будет отсортирован сначала по типу, а оставшиеся по алфавиту. Но те, что по типу, будут отсортированы в обратном порядке алфавита. И, да, не используя es6.


Ответы (1 шт):

Автор решения: Zhihar

вам просто надо расставить приоритеты рассмотрения объектов при сортировке:

  1. сначала рассматривать ситуацию, когда один из объектов имеет тип point - в этом случае он первый в сортировке

  2. затем рассматривать ситуацию, когда оба объекта имеют тип point - тогда сравнивать по полю name и у кого имя меньше, тот первый в сортировке

  3. затем рассматривать ситуацию, когда оба объекта имеют тип отличный от point - тогда сравнивать по полю name и у кого имя меньше, тот первый в сортировке

т.е. должно получиться что-то подобное:

list.sort( (a,b) => {
    // сначала первым приоритетом работаем с объектами типа `point`
    if (a.type === 'point && a.type !== 'point)
        return = -1;

    if (a.type !== 'point && a.type === 'point)
        return = 1;

    // если оба объекта типа `point` - сортируем по полю `name`
    if (a.type === 'point && a.type === 'point)
        return a.name.localeCompare(b.name);

    // все остальные объекты сортируем по полю `name`
    return a.name.localeCompare(b.name);
});

вообще любую сортировку такого типа можно провести с помощью одной функции сравнения

→ Ссылка