This is not your original approach, but you can create an actual tree from your data, for example:
function TreeNode(data) { this.data = data; this.parent = null; this.children = []; } TreeNode.comparer = function (a, b) { return a.data.sort < b.data.sort ? 0 : 1; }; TreeNode.prototype.sortRecursive = function () { this.children.sort(TreeNode.comparer); for (var i=0, l=this.children.length; i<l; i++) { this.children[i].sortRecursive(); } return this; }; function toTree(data) { var nodeById = {}, i = 0, l = data.length, node; nodeById[0] = new TreeNode();
With this setting, you get neatly nested nodes with a simple call:
var tree = toTree(data);
TreeNode: 0
parent -> null
data -> undefined
childen -> Array [
TreeNode: 1
parent -> TreeNode: 0
data -> {index: 4, sort: 4, parent: 0}
childen -> Array []
TreeNode: 2
parent -> TreeNode: 0
data -> {index: 2, sort: 7, parent: 0}
childen -> Array []
TreeNode: 3
parent -> TreeNode: 0
data -> {index: 1, sort: 10, parent: 0}
childen -> Array [
TreeNode: 4
parent -> TreeNode: 3
data -> {index: 5, sort: 13, parent: 1}
childen -> Array [
]
TreeNode: 5
parent -> TreeNode: 3
data -> {index: 3, sort: 15, parent: 1}
childen -> Array [
... and so on ...
]
]
]
Once you have this tree object, you can do several things with it, including moving it recursively in the expected order.
To do this, you can add a helper function that performs a depth traverse and performs the payload function f for each node:
TreeNode.prototype.walk = function(f, recursive) { for (var i=0, l=this.children.length; i<l; i++) { var child = this.children[i]; f.apply(child, Array.prototype.slice.call(arguments, 2)); if (recursive) child.walk.apply(child, arguments); } }
and name it as follows:
tree.walk(function () { console.log(this.data) }, true);
which will produce:
{index: 4, sort: 4, parent: 0}
{index: 2, sort: 7, parent: 0}
{index: 1, sort: 10, parent: 0}
{index: 5, sort: 13, parent: 1}
{index: 8, sort: 6, parent: 5}
{index: 7, sort: 2, parent: 8}
{index: 6, sort: 20, parent: 5}
{index: 3, sort: 15, parent: 1}
Use more complex payload functions for other effects, for example, add table rows to a table with jQuery or elements in a <select> field.