0

I have terms as below:

var terms = [
        { id: 1, name: "Name 1", parent: null },
        { id: 2, name: "Name 2", parent: 6 },
        { id: 3, name: "Name 3", parent: null },
        { id: 4, name: "Name 4", parent: 2},
        { id: 5, name: "Name 5", parent: 3 },
        { id: 6, name: "Name 6", parent: null },
        { id: 7, name: "Name 7", parent: 3 },
        { id: 8, name: "Name 8", parent: 9 },
        { id: 9, name: "Name 9", parent: 4 }
];

Now, I want to process term to have the output:

var orderedTerms = [
        { id: 1, name: "Name 1", parent: null , deep: 0},
        { id: 3, name: "Name 3", parent: null , deep: 0},
        { id: 5, name: "Name 5", parent: 3 , deep: 1},
        { id: 7, name: "Name 7", parent: 3 , deep: 1},
        { id: 6, name: "Name 6", parent: null , deep: 0},
        { id: 2, name: "Name 2", parent: 6, deep: 1},
        { id: 4, name: "Name 4", parent: 2, deep: 2},
        { id: 9, name: "Name 9", parent: 4, deep: 3},
        { id: 8, name: "Name 8", parent: 9, deep: 4 }
];

I think that someone can help me do it with Javascript (NodeJS). Thank you in advance.

8
  • Did you try anything? Commented Nov 1, 2015 at 9:22
  • Can you please share what you tried so far? It's easier to get a suggestion on what went wrong for you rather than someone providing the whole solution. Commented Nov 1, 2015 at 9:23
  • what is the sort criteria (id, parent or deep)? Commented Nov 1, 2015 at 9:26
  • I will try to do something and update my question later. However, if someone did it, they can help me beforehand Commented Nov 1, 2015 at 9:27
  • I would suggest to actually paste some code showing what you're trying to do.. Commented Nov 1, 2015 at 9:28

2 Answers 2

2

The code below should help you:

var terms = [
  { id: 1, name: "Name 1", parent: null },
  { id: 2, name: "Name 2", parent: 6 },
  { id: 3, name: "Name 3", parent: null },
  { id: 4, name: "Name 4", parent: 2},
  { id: 5, name: "Name 5", parent: 3 },
  { id: 6, name: "Name 6", parent: null },
  { id: 7, name: "Name 7", parent: 3 },
  { id: 8, name: "Name 8", parent: 9 },
  { id: 9, name: "Name 9", parent: 4 }
];

var deep0 = terms.filter(function(term) {
  if (term.parent === null) {
    term.deep = 0;
    return true;
  }
  return false;
});

function makeTree(source, arr, final) {
  if (!final)
    final = arr.slice();
  
  if (arr.length > 0) {
    var deep = arr[0].deep + 1;
  
    source.forEach(function (item, i) {
      if (arr.map(function(term) {
        return term.id;
      }).indexOf(item.parent) >= 0) {
        item.deep = deep;
        var idx = final.map(function(term) {
          return (term.id === item.parent || term.parent === item.parent);
        }).lastIndexOf(true);
        final.splice(idx + 1, 0, item);
      }
    });
  
    makeTree(source, final.filter(function(term) {
      return term.deep === deep;
    }), final);
  }
  
  return final;
}

var final = makeTree(terms, deep0);

document.body.innerHTML = '<pre><code>' + JSON.stringify(final, null, 2) + '</code></pre>';

The hole idea behind the code was to firstly find all the items which didn't have a parent, and then recursively iterate through their children (deeply), inserting them in the correct order into the final array.

If you have any doubts, leave a comment.

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

1 Comment

Thank for your understanding my question. Your code works for me.
1

Just a little recursion will do.

function getTree(parent, level) {
    level = level || 0;
    terms.forEach(function (a) {
        if (a.parent === parent) {
            orderedTerms.push({ id: a.id, name: a.name, parent: a.parent, deep: level });
            getTree(a.id, level + 1);
        }
    });
}

var terms = [
        { id: 1, name: "Name 1", parent: null },
        { id: 2, name: "Name 2", parent: 6 },
        { id: 3, name: "Name 3", parent: null },
        { id: 4, name: "Name 4", parent: 2 },
        { id: 5, name: "Name 5", parent: 3 },
        { id: 6, name: "Name 6", parent: null },
        { id: 7, name: "Name 7", parent: 3 },
        { id: 8, name: "Name 8", parent: 9 },
        { id: 9, name: "Name 9", parent: 4 }
    ],
    orderedTerms = [];

getTree(null);
document.write('<pre>' + JSON.stringify(orderedTerms, 0, 4) + '</pre>');

Bonus: Version with temporary storage.

function sortTree(array) {

    function getTree(parent, level) {
        temp[parent] && temp[parent].forEach(function (a) {
            result.push({ id: array[a].id, name: array[a].name, parent: array[a].parent, deep: level });
            getTree(array[a].id, level + 1);
        });
    }

    var temp = {},
        result = [];

    array.forEach(function (a, i) {
        temp[a.parent] = temp[a.parent] || [];
        temp[a.parent].push(i);
    });
    getTree(null, 0);
    return result;
}

var terms = [
        { id: 1, name: "Name 1", parent: null },
        { id: 2, name: "Name 2", parent: 6 },
        { id: 3, name: "Name 3", parent: null },
        { id: 4, name: "Name 4", parent: 2 },
        { id: 5, name: "Name 5", parent: 3 },
        { id: 6, name: "Name 6", parent: null },
        { id: 7, name: "Name 7", parent: 3 },
        { id: 8, name: "Name 8", parent: 9 },
        { id: 9, name: "Name 9", parent: 4 }
    ];

document.write('<pre>' + JSON.stringify(sortTree(terms), 0, 4) + '</pre>');

1 Comment

Thanks for your answer. I do not know why many people are not able to understand my question :)

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.