3

I would like to loop through a deeply nested object, and sort each level based on a property. In this case its id

Here's my object (there will me more levels, I just added 3 levels here for readability):

const myObj = [
  {
    id: 15,
    children: [
      {
        id: 9,
        children: [
          {
            id: 4,
            children: []
          },
          {
            id: 1,
            children: []
          }
        ]
      },
      {
        id: 4,
        children: [
          {
            id: 35,
            children: [
              {
                id: 12,
                children: []
              },
              {
                id: 8,
                children: []
              }
            ]
          },
          {
            id: 30,
            children: [],
          }
        ]
      },
    ]
  },
  {
    id: 2,
    children: [
      {
        id: 9,
        children: []
      },
      {
        id: 3,
        children: []
      },
    ]
  }
]

Here's the desired output:

const myObj = [
  {
    id: 2,
    children: [
      {
        id: 3,
        children: []
      },
      {
        id: 9,
        children: []
      }
    ]
  },
  {
    id: 15,
    children: [
      {
        id: 4,
        children: [
          {
            id: 30,
            children: [],
          },
          {
            id: 35,
            children: [
              {
                id: 8,
                children: []
              },
              {
                id: 12,
                children: []
              }
            ]
          },
        ]
      },
      {
        id: 9,
        children: [
          {
            id: 1,
            children: []
          },
          {
            id: 4,
            children: []
          }
        ]
      },
    ]
  }
]

And here's my attempt at sorting it:

const myObj = [{id:15,children:[{id:9,children:[{id:4,children:[]},{id:1,children:[]}]},{id:4,children:[{id:35,children:[{id:12,children:[]},{id:8,children:[]}]},{id:30,children:[],}]},]},{id:2,children:[{id:9,children:[]},{id:3,children:[]},]}]

function sortByOrderIndex(obj) {
  obj.sort((a, b) => (a.orderindex > b.orderindex) ? 1 : ((b.orderindex > a.orderindex) ? -1 : 0));

  return obj;
}

function sortNestedObj(obj) {
  sortByOrderIndex(obj);

  for (let i = 0; i < obj.length; i++) {
    const t = obj[i];

    if (t.children.length !== 0) {
      sortNestedObj(t.children);
    } else {
      return;
    }
  }
}

console.log(sortByOrderIndex(myObj))

I've created a function that sorts an object, and then tried to create another object that loops through each object that has children and sort those children using the first function. And if those children have children, then sort those and so forth until a child has no children.

4 Answers 4

4

You could recursively sort the array and it's object's children like this:

const myObj = [{id:15,children:[{id:9,children:[{id:4,children:[]},{id:1,children:[]}]},{id:4,children:[{id:35,children:[{id:12,children:[]},{id:8,children:[]}]},{id:30,children:[],}]},]},{id:2,children:[{id:9,children:[]},{id:3,children:[]},]}]

function sortArray(array) {
  array.sort((a, b) => a.id - b.id);
  array.forEach(a => {
    if (a.children && a.children.length > 0)
      sortArray(a.children)
  })
  return array;
}

console.log(sortArray(myObj))

Sign up to request clarification or add additional context in comments.

Comments

1

You can make a recursive sorting function:

const myObj = [{id:15,children:[{id:9,children:[{id:4,children:[]},{id:1,children:[]}]},{id:4,children:[{id:35,children:[{id:12,children:[]},{id:8,children:[]}]},{id:30,children:[],}]},]},{id:2,children:[{id:9,children:[]},{id:3,children:[]},]}]

const orderChildren = obj => {
  obj.children.sort((a, b) => a.id - b.id);
  if (obj.children.some(o => o.children.length)) {
    obj.children.forEach(child => orderChildren(child));
  }
  return obj;
};

const myNewObj = myObj.map(o => orderChildren(o)).sort((a, b) => a.id - b.id);

console.log(myNewObj);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

1

You can do:

const myObj = [{id: 15,children: [{id: 9,children: [{id: 4,children: []},{id: 1,children: []}]},{id: 4,children: [{id: 35,children: [{id: 12,children: []},{id: 8,children: []}]},{id: 30,children: [],}]},]},{id: 2,children: [{id: 9,children: []},{id: 3,children: []},]}];
const deepSortById = arr => (arr.forEach(a => a.children && deepSortById(a.children)), arr.sort((a, b) => a.id - b.id));

const result = deepSortById(myObj);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

0

I created generic solution for sorting nested arrays by id. My solution works with any nested array and sorts it according to id property. Or by any other property you specify in the method's seconds parameter.

function sortNestedArrays(obj, sortPropertyName) {
    Object.keys(obj).forEach((key) => {
        if (Array.isArray(obj[key])) {
            obj[key].sort((a, b) => a[sortPropertyName] - b[sortPropertyName]);
        }

        if (!!obj[key] && (typeof obj[key] === 'object' || Array.isArray(obj[key]))) {
            sortNestedArrays(obj[key], sortPropertyName);
        }
    });

    return obj;
}

Usage is following:

obj = sortNestedArrays(obj, 'id');

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.