@fgehte

Как отрефакторить функцию для сортировки массива объектов?

Есть встроенный метод для сортировки массива sort(), мне нужно написать функцию sorting, которая принимает 2 аргумента. 1-ый массив объектов, 2-ой свойство по которому нужно отсортировать этот самый массив.
При передачи в функцию св-во объекта 1-го уровня, при передачи 2-го уровня не работает, как переписать функцию, чтобы она работала независимо от кол-ва уровней св-ва? Надеюсь объяснил более менее понятно.
const arrays = [
  {
    length: 1
    year: 2000,
    comments: {
       count: 10
    }
  },
  {
    length: 5
    year: 2020,
    comments: {
       count: 5
    }
  },
  {
    length: 45
    year: 2005,
    comments: {
       count: 7
    }
  },
]
const sorting = (arr, proper) {
  return arr.slice().sort((a,b) => b[proper] - a[proper]);
};
console.log(sorting(arrays, `length`)) // работает
console.log(sorting(arrays, `year`)) // работает
console.log(sorting(arrays, `comments.count`)) // не работает
  • Вопрос задан
  • 145 просмотров
Решения вопроса 2
Aetae
@Aetae Куратор тега JavaScript
Тлен
Лучше всего заюзать функцию sortBy из lodash, которая делает именно это, и не парить мозг. Иначе тебе придётся написать аналог функции lodash get, а там есть свои подводные камни.
Но если примитивно:
function get(value, str) {
  for(const key of str.split('.')) {
    if(value && key in value) value = value[key];
    else return void 0;
  }
  return value;
}
arr.slice().sort((a,b) => get(b,proper) - get(a,proper));
Ответ написан
Комментировать
0xD34F
@0xD34F Куратор тега JavaScript
Режем второй параметр на куски, перебираем полученный массив ключей для извлечения значения вложенного свойства - следующее значение будет свойством предыдущего с именем, равным текущему элементу массива:

const sorted = (arr, path) => arr
  .map(function(n) {
    return [ n, this.reduce((p, c) => p?.[c], n) ];
  }, path.split('.'))
  .sort((a, b) => a[1] - b[1])
  .map(n => n[0]);

А вообще, предлагаю изменить тип второго параметра со строки на функцию:

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


const sortedByCommentsCount = sorted(arr, n => n.comments.count);
const sortedByLengthDesc = sorted(arr, n => -n.length);
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

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