Guedda
@Guedda
Начинающий front-end разработчик

Как отсортировать массив объектов по массиву значений определённого свойства?

Есть массив объектов:

messages = [
      {"id":1, "language":"ar"},
      {"id":2, "language":"en"},
      {"id":3, "language":"su"},
      {"id":4, "language":"mo"},
      {"id":5, "language":"da"}
];

И есть массив языков, например, он может быть таким:

sortableLanguages = ["su", "ar"];

В итоге должно отсортироваться так:

messages = [
      {"id":3, "language":"su"},
      {"id":1, "language":"ar"},
      {"id":2, "language":"en"},
      {"id":4, "language":"mo"},
      {"id":5, "language":"da"}
];

Т.е., сначала сортируется по массиву sortableLanguages, а потом остальные as is.
Дошел до такого кода:

messages.sort((a, b) => {
  if (sortableLanguages.indexOf(a.language) === -1) return -1;
  return sortableLanguages.indexOf(a.language) < sortableLanguages.indexOf(b.language) ? 1 : 0;
});

Но почему-то получается всё наоборот.
  • Вопрос задан
  • 267 просмотров
Решения вопроса 1
0xD34F
@0xD34F Куратор тега JavaScript
Сортируем существующий массив:

messages.sort((a, b) => {
  [ a, b ] = [ a, b ].map(n => sortableLanguages.indexOf(n.language));
  return a === -1 ? 1 : b === -1 ? -1 : a - b;
});

Собираем отсортированный новый:

const sorted = (arr, key) => arr
  .map(n => [ n, key(n) ])
  .sort((a, b) => a[1] - b[1])
  .map(n => n[0]);


const order = Object.fromEntries(sortableLanguages.map((n, i) => [ n, i + 1 ]));
const sortedMessages = sorted(messages, n => order[n.language] || Number.MAX_SAFE_INTEGER);

// или

function sorted(arr, order, key) {
  const ordered = new Map(order.map(n => [ n, [] ]));
  const unordered = [];

  arr.forEach(n => (ordered.get(key(n)) || unordered).push(n));

  return [].concat(...ordered.values(), unordered);
}


const sortedMessages = sorted(messages, sortableLanguages, n => n.language);
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
fallus
@fallus
messages.sort(function(val){
  if(sortableLanguages.indexOf(val.language) != -1) return -1
})


Я хз, у меня вернулось это:
0: {id: 3, language: "su"}
1: {id: 1, language: "ar"}
2: {id: 2, language: "en"}
3: {id: 4, language: "mo"}
4: {id: 5, language: "da"}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы