Как упорядочить массив по родительским элементам в JavaScript

Пример простой, но он поможет мне решить сложную проблему для таблицы данных, созданной с помощью angular и material, которая получает массив. Я получаю массив объектов, которые я хочу организовать по происхождению, как следующий пример, который я представляю в простой форме, чтобы не запутывать вопрос со сложными данными.

Я получаю данные как array1:

array1 = [
  {id:1, parent_id:0, data:'txt'},
  {id:2, parent_id:0, data:'txt'},
  {id:3, parent_id:1, data:'txt'},
  {id:4, parent_id:1, data:'txt'},
  {id:5, parent_id:0, data:'txt'},
  {id:6, parent_id:0, data:'txt'},
  {id:7, parent_id:5, data:'txt'},
];

и я хочу организовать его как array2.

array2 = [
  {id:1, parent_id:0, data:'txt'},
  {id:3, parent_id:1, data:'txt'},
  {id:4, parent_id:1, data:'txt'},
  {id:2, parent_id:0, data:'txt'},
  {id:5, parent_id:0, data:'txt'},
  {id:7, parent_id:5, data:'txt'},
  {id:6, parent_id:0, data:'txt'},
];

Какова логика сортировки второго массива?

31piy 09.04.2019 05:34

Чем массив2 отличается от массива1? Я имею в виду, как именно вы хотите организовать?

Gourishankar 09.04.2019 05:34

А что вы пробовали?

charlietfl 09.04.2019 05:35

Знакомы ли вы с понятиями поиска в глубину и/или топологической сортировки?

Ray Toal 09.04.2019 05:35

Для всех, кто просит разъяснений о том, как именно было сформировано array2, нарисуйте подразумеваемое дерево (поле parent_id — это идентификатор родителя), затем выполните поиск в глубину, и вы получите именно array2.

Ray Toal 09.04.2019 05:36
lodash.com/docs/4.17.11#сортировка по
Matt Habermehl 09.04.2019 05:59
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
6
89
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Здесь у вас есть одно возможное решение, использующее сначала Массив.фильтр() для получения объектов без родителей (то есть объектов, где parent_id:0), а затем сортировать их с помощью свойства id. После этого мы используем Массив.уменьшить(), чтобы получить список дочерних элементов для каждого из предыдущих объектов, отсортировать эти дочерние элементы и поместить их сразу после его родителя. Однако это не эффективное решение, возможно, есть лучшие варианты.

const array1 = [
  {id:1, parent_id:0, data:'txt'},
  {id:2, parent_id:0, data:'txt'},
  {id:3, parent_id:1, data:'txt'},
  {id:4, parent_id:1, data:'txt'},
  {id:5, parent_id:0, data:'txt'},
  {id:6, parent_id:0, data:'txt'},
  {id:7, parent_id:5, data:'txt'},
];

let res = array1
    .filter(({parent_id}) => parent_id === 0)
    .sort((a, b) => a.id - b.id)
    .reduce((acc, curr) =>
    {
        const children = array1
            .filter(({parent_id}) => parent_id === curr.id)
            .sort((a, b) => a.id - b.id);

        return [...acc, curr, ...children];
    }, []);

console.info(res);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

Решение исходит из аналогичного вопроса, который я задал некоторое время назад, вы также можете проверить там другие ответы и мой первый подход (лучше по производительности, но не общий, у него были некоторые ограничения, как описано там) для решения такой проблемы: Сортировка массива категорий и подкатегорий

Другие вопросы по теме