简体   繁体   中英

Sorting multi level parent child object in js

I have the following array of objects. I would like to sort the array so that all child options are placed next to its parent. Most of the solutions are on tree structure where I need it in a flat structure.

Also I need a level key which indicates the level of the option.

[
 {
    "id": 1,
    "name": "Parent"
 },
 {
    "id": 2,
    "name": "Child 1",
    "parent_id": 1
 },
 {
    "id": 3,
    "name": "Grand Child 1",
    "parent_id": 2
 },
 {
    "id": 4,
    "name": "Grand Child 2",
    "parent_id": 2
 },
 {
    "id": 5,
    "name": "Child 2",
    "parent_id": 1
 },
 {
    "id": 7,
    "name": "Grand Child 3",
    "parent_id": 2
 },
]

I want all child to be places next to it's parent like this

[
 {
    "id": 1,
    "name": "Parent",
    "level": 1
 },
 {
    "id": 2,
    "name": "Child 1",
    "parent_id": 1,
    "level": 2
 },
 {
    "id": 3,
    "name": "Grand Child 1",
    "parent_id": 2,
    "level": 3
 },
 {
    "id": 4,
    "name": "Grand Child 2",
    "parent_id": 2,
    "level": 3
 },
 {
    "id": 7,
    "name": "Grand Child 3",
    "parent_id": 2,
    "level": 3
 },
 {
    "id": 5,
    "name": "Child 2",
    "parent_id": 1,
    "level": 2
 },
]

I've seen a solution but it works only 1 level

You could try this solution:

/**
 * Provided dataset example.
 */
const arrayToBeSorted = [
  { id: 1, name: 'Parent' },
  { id: 2, name: 'Child 1', parent_id: 1 },
  { id: 3, name: 'Grand Child 1', parent_id: 2 },
  { id: 4, name: 'Grand Child 2', parent_id: 2 },
  { id: 5, name: 'Child 2', parent_id: 1 },
  { id: 7, name: 'Grand Child 3', parent_id: 2 }
];

/**
 *
 * The array is recursively sorted by level, and each element is given the level property.
 * @param {Array} list
 * @param {Object} parent
 * @returns {Array}
 */
const recursiveArraySort = (list, parent = { id: undefined, level: 0 }) => {
  let result = [];

  /**
   * Get every element whose parent_id attribute matches the parent's id.
   */
  const children = list.filter(item => item.parent_id === parent.id);

  /**
   * Set the level based on the parent level for each element identified,
   * add them to the result array, then recursively sort the children.
   */
  children.forEach(child => {
    child.level = parent.level + 1;
    result = [...result, child, ...recursiveArraySort(list, child)];
  });

  return result;
};

const sortedArray = recursiveArraySort(arrayToBeSorted);

console.log(sortedArray);

Console.log's result:

[
  { id: 1, name: 'Parent', level: 1 },
  { id: 2, name: 'Child 1', parent_id: 1, level: 2 },
  { id: 3, name: 'Grand Child 1', parent_id: 2, level: 3 },
  { id: 4, name: 'Grand Child 2', parent_id: 2, level: 3 },
  { id: 7, name: 'Grand Child 3', parent_id: 2, level: 3 },
  { id: 5, name: 'Child 2', parent_id: 1, level: 2 }
]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM