2

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

1
  • Just iterate through the list. Since each child has the id of the parent, the level of the child is the parent level + 1. Commented Aug 16, 2022 at 17:05

1 Answer 1

4

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 }
]
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.