This
// create an index for(var index in model) { if (!model.hasOwnProperty(index)) { continue; } this.index[model[index].right] = index; }could be
// create an index for(var index in model) { if (model.hasOwnProperty(index)) { this.index[model[index].right] = index; } }by avoiding the
continuestatementThis
try { var node = new NestedSetModelNode(model[entry], model, this.index); this.model.push(node); } catch(e) {}intrigues me, I don't see what could go wrong with this code that you need a
try/catch, even more intriguing is that you fail silently here, potentially providing wrong query results later in the gameThis part could be faster for strict comparisons:
for (var i = 0; i <= keys[1].length; i++) { var prop = keys[1][i]; if (a[prop] !== b[prop]) { return false; } } if (!strict) { return true; } for (var prop in keys[0]) { if (b[prop] !== undefined && a[prop] !== b[prop]) { return false; } if (typeof a[prop] === 'object' && this.compareNodes(a[prop], b[prop], true) === false) { return false } }What you do here every time you check for strict comparison is comparing
bwithausing!=and then again comparingawithbusing!==. Since you know for strict comparison that the key count is the same, this is overkill. Furthermore I have doubts on(b[prop] !== undefined && a[prop] !== b[prop])if the value ofb[prop]isundefinedand the value of a[prop] is notundefined, then the comparison should be false. Furthermore I am not sure why youthis.compareNodesin case of an object, ifa[prop] === b[prop], then the nodes cannot be different because it is the same object (as I understand it), if you want to really compare two different objects for the same properties, then that should should be before the!==check.I would counter propose something like this:
if (!strict) { for (var prop in keys[1]) { //I still wonder, why 1, not 0? if (b[prop] != a[prop]) { return false; } } } else { for (var prop in keys[0]) { if (typeof a[prop] == 'object') { if( !this.compareNodes(a[prop], b[prop], true)) { return false; } } else if (a[prop] !== b[prop]) { return false; } } } //We made it thru, a and b are equal (enough) return true;Perhaps consider renaming
NestedSetModel.prototype.findtofindFirst, since it only returns the first matchThis
var self = this; Object.keys(node).forEach(function(prop) { self[prop] = node[prop]; });only needs
selfbecause of the forEach, from a style/performance perspective you could avoid this by going to a fasterforloop.This
this.model.map(function(node) { if (self.left > node.left && self.right < node.right) { parents.push(new NestedSetModelNode(node, self.model, self.index)); } });utilizes
mapwhich builds an array for you, if you are not going to use the results ofmap, then you should useforEach, and since you are interested in speed, you should use a simpleforloop.On the whole I dont get your data structur with
leftandright, I would have loved to see a small example with dataI also don't get the difference between
childrenanddescendantsunless you meandescendantsalso include grandchildren etc. I think you could find a better name thandescendants.An excellent point of @Megawac, which I completely missed is that using
for .. inis considered very bad practice for arraysconsidered very bad practice for arrays. If you simply use the regularforloop then that will be faster because you no longer need checkhasOwnPropertyevery single time.
This
// create an index for(var index in model) { if (!model.hasOwnProperty(index)) { continue; } this.index[model[index].right] = index; }could be
// create an index for(var index in model) { if (model.hasOwnProperty(index)) { this.index[model[index].right] = index; } }by avoiding the
continuestatementThis
try { var node = new NestedSetModelNode(model[entry], model, this.index); this.model.push(node); } catch(e) {}intrigues me, I don't see what could go wrong with this code that you need a
try/catch, even more intriguing is that you fail silently here, potentially providing wrong query results later in the gameThis part could be faster for strict comparisons:
for (var i = 0; i <= keys[1].length; i++) { var prop = keys[1][i]; if (a[prop] !== b[prop]) { return false; } } if (!strict) { return true; } for (var prop in keys[0]) { if (b[prop] !== undefined && a[prop] !== b[prop]) { return false; } if (typeof a[prop] === 'object' && this.compareNodes(a[prop], b[prop], true) === false) { return false } }What you do here every time you check for strict comparison is comparing
bwithausing!=and then again comparingawithbusing!==. Since you know for strict comparison that the key count is the same, this is overkill. Furthermore I have doubts on(b[prop] !== undefined && a[prop] !== b[prop])if the value ofb[prop]isundefinedand the value of a[prop] is notundefined, then the comparison should be false. Furthermore I am not sure why youthis.compareNodesin case of an object, ifa[prop] === b[prop], then the nodes cannot be different because it is the same object (as I understand it), if you want to really compare two different objects for the same properties, then that should should be before the!==check.I would counter propose something like this:
if (!strict) { for (var prop in keys[1]) { //I still wonder, why 1, not 0? if (b[prop] != a[prop]) { return false; } } } else { for (var prop in keys[0]) { if (typeof a[prop] == 'object') { if( !this.compareNodes(a[prop], b[prop], true)) { return false; } } else if (a[prop] !== b[prop]) { return false; } } } //We made it thru, a and b are equal (enough) return true;Perhaps consider renaming
NestedSetModel.prototype.findtofindFirst, since it only returns the first matchThis
var self = this; Object.keys(node).forEach(function(prop) { self[prop] = node[prop]; });only needs
selfbecause of the forEach, from a style/performance perspective you could avoid this by going to a fasterforloop.This
this.model.map(function(node) { if (self.left > node.left && self.right < node.right) { parents.push(new NestedSetModelNode(node, self.model, self.index)); } });utilizes
mapwhich builds an array for you, if you are not going to use the results ofmap, then you should useforEach, and since you are interested in speed, you should use a simpleforloop.On the whole I dont get your data structur with
leftandright, I would have loved to see a small example with dataI also don't get the difference between
childrenanddescendantsunless you meandescendantsalso include grandchildren etc. I think you could find a better name thandescendants.An excellent point of @Megawac, which I completely missed is that using
for .. inis considered very bad practice for arrays. If you simply use the regularforloop then that will be faster because you no longer need checkhasOwnPropertyevery single time.
This
// create an index for(var index in model) { if (!model.hasOwnProperty(index)) { continue; } this.index[model[index].right] = index; }could be
// create an index for(var index in model) { if (model.hasOwnProperty(index)) { this.index[model[index].right] = index; } }by avoiding the
continuestatementThis
try { var node = new NestedSetModelNode(model[entry], model, this.index); this.model.push(node); } catch(e) {}intrigues me, I don't see what could go wrong with this code that you need a
try/catch, even more intriguing is that you fail silently here, potentially providing wrong query results later in the gameThis part could be faster for strict comparisons:
for (var i = 0; i <= keys[1].length; i++) { var prop = keys[1][i]; if (a[prop] !== b[prop]) { return false; } } if (!strict) { return true; } for (var prop in keys[0]) { if (b[prop] !== undefined && a[prop] !== b[prop]) { return false; } if (typeof a[prop] === 'object' && this.compareNodes(a[prop], b[prop], true) === false) { return false } }What you do here every time you check for strict comparison is comparing
bwithausing!=and then again comparingawithbusing!==. Since you know for strict comparison that the key count is the same, this is overkill. Furthermore I have doubts on(b[prop] !== undefined && a[prop] !== b[prop])if the value ofb[prop]isundefinedand the value of a[prop] is notundefined, then the comparison should be false. Furthermore I am not sure why youthis.compareNodesin case of an object, ifa[prop] === b[prop], then the nodes cannot be different because it is the same object (as I understand it), if you want to really compare two different objects for the same properties, then that should should be before the!==check.I would counter propose something like this:
if (!strict) { for (var prop in keys[1]) { //I still wonder, why 1, not 0? if (b[prop] != a[prop]) { return false; } } } else { for (var prop in keys[0]) { if (typeof a[prop] == 'object') { if( !this.compareNodes(a[prop], b[prop], true)) { return false; } } else if (a[prop] !== b[prop]) { return false; } } } //We made it thru, a and b are equal (enough) return true;Perhaps consider renaming
NestedSetModel.prototype.findtofindFirst, since it only returns the first matchThis
var self = this; Object.keys(node).forEach(function(prop) { self[prop] = node[prop]; });only needs
selfbecause of the forEach, from a style/performance perspective you could avoid this by going to a fasterforloop.This
this.model.map(function(node) { if (self.left > node.left && self.right < node.right) { parents.push(new NestedSetModelNode(node, self.model, self.index)); } });utilizes
mapwhich builds an array for you, if you are not going to use the results ofmap, then you should useforEach, and since you are interested in speed, you should use a simpleforloop.On the whole I dont get your data structur with
leftandright, I would have loved to see a small example with dataI also don't get the difference between
childrenanddescendantsunless you meandescendantsalso include grandchildren etc. I think you could find a better name thandescendants.An excellent point of @Megawac, which I completely missed is that using
for .. inis considered very bad practice for arrays. If you simply use the regularforloop then that will be faster because you no longer need checkhasOwnPropertyevery single time.
This
// create an index for(var index in model) { if (!model.hasOwnProperty(index)) { continue; } this.index[model[index].right] = index; }could be
// create an index for(var index in model) { if (model.hasOwnProperty(index)) { this.index[model[index].right] = index; } }by avoiding the
continuestatementThis
try { var node = new NestedSetModelNode(model[entry], model, this.index); this.model.push(node); } catch(e) {}intrigues me, I don't see what could go wrong with this code that you need a
try/catch, even more intriguing is that you fail silently here, potentially providing wrong query results later in the gameThis part could be faster for strict comparisons:
for (var i = 0; i <= keys[1].length; i++) { var prop = keys[1][i]; if (a[prop] !== b[prop]) { return false; } } if (!strict) { return true; } for (var prop in keys[0]) { if (b[prop] !== undefined && a[prop] !== b[prop]) { return false; } if (typeof a[prop] === 'object' && this.compareNodes(a[prop], b[prop], true) === false) { return false } }What you do here every time you check for strict comparison is comparing
bwithausing!=and then again comparingawithbusing!==. Since you know for strict comparison that the key count is the same, this is overkill. Furthermore I have doubts on(b[prop] !== undefined && a[prop] !== b[prop])if the value ofb[prop]isundefinedand the value of a[prop] is notundefined, then the comparison should be false. Furthermore I am not sure why youthis.compareNodesin case of an object, ifa[prop] === b[prop], then the nodes cannot be different because it is the same object (as I understand it), if you want to really compare two different objects for the same properties, then that should should be before the!==check.I would counter propose something like this:
if (!strict) { for (var prop in keys[1]) { //I still wonder, why 1, not 0? if (b[prop] != a[prop]) { return false; } } } else { for (var prop in keys[0]) { if (typeof a[prop] == 'object') { if( !this.compareNodes(a[prop], b[prop], true)) { return false; } } else if (a[prop] !== b[prop]) { return false; } } } //We made it thru, a and b are equal (enough) return true;Perhaps consider renaming
NestedSetModel.prototype.findtofindFirst, since it only returns the first matchThis
var self = this; Object.keys(node).forEach(function(prop) { self[prop] = node[prop]; });only needs
selfbecause of the forEach, from a style/performance perspective you could avoid this by going to a fasterforloop.This
this.model.map(function(node) { if (self.left > node.left && self.right < node.right) { parents.push(new NestedSetModelNode(node, self.model, self.index)); } });utilizes
mapwhich builds an array for you, if you are not going to use the results ofmap, then you should useforEach, and since you are interested in speed, you should use a simpleforloop.On the whole I dont get your data structur with
leftandright, I would have loved to see a small example with dataI also don't get the difference between
childrenanddescendantsunless you meandescendantsalso include grandchildren etc. I think you could find a better name thandescendants.An excellent point of @Megawac, which I completely missed is that using
for .. inis considered very bad practice for arrays. If you simply use the regularforloop then that will be faster because you no longer need checkhasOwnPropertyevery single time.
This
// create an index for(var index in model) { if (!model.hasOwnProperty(index)) { continue; } this.index[model[index].right] = index; }could be
// create an index for(var index in model) { if (model.hasOwnProperty(index)) { this.index[model[index].right] = index; } }by avoiding the
continuestatementThis
try { var node = new NestedSetModelNode(model[entry], model, this.index); this.model.push(node); } catch(e) {}intrigues me, I don't see what could go wrong with this code that you need a
try/catch, even more intriguing is that you fail silently here, potentially providing wrong query results later in the gameThis part could be faster for strict comparisons:
for (var i = 0; i <= keys[1].length; i++) { var prop = keys[1][i]; if (a[prop] !== b[prop]) { return false; } } if (!strict) { return true; } for (var prop in keys[0]) { if (b[prop] !== undefined && a[prop] !== b[prop]) { return false; } if (typeof a[prop] === 'object' && this.compareNodes(a[prop], b[prop], true) === false) { return false } }What you do here every time you check for strict comparison is comparing
bwithausing!=and then again comparingawithbusing!==. Since you know for strict comparison that the key count is the same, this is overkill. Furthermore I have doubts on(b[prop] !== undefined && a[prop] !== b[prop])if the value ofb[prop]isundefinedand the value of a[prop] is notundefined, then the comparison should be false. Furthermore I am not sure why youthis.compareNodesin case of an object, ifa[prop] === b[prop], then the nodes cannot be different because it is the same object (as I understand it), if you want to really compare two different objects for the same properties, then that should should be before the!==check.I would counter propose something like this:
if (!strict) { for (var prop in keys[1]) { //I still wonder, why 1, not 0? if (b[prop] != a[prop]) { return false; } } } else { for (var prop in keys[0]) { if (typeof a[prop] == 'object') { if( !this.compareNodes(a[prop], b[prop], true)) { return false; } } else if (a[prop] !== b[prop]) { return false; } } } //We made it thru, a and b are equal (enough) return true;Perhaps consider renaming
NestedSetModel.prototype.findtofindFirst, since it only returns the first matchThis
var self = this; Object.keys(node).forEach(function(prop) { self[prop] = node[prop]; });only needs
selfbecause of the forEach, from a style/performance perspective you could avoid this by going to a fasterforloop.This
this.model.map(function(node) { if (self.left > node.left && self.right < node.right) { parents.push(new NestedSetModelNode(node, self.model, self.index)); } });utilizes
mapwhich builds an array for you, if you are not going to use the results ofmap, then you should useforEach, and since you are interested in speed, you should use a simpleforloop.On the whole I dont get your data structur with
leftandright, I would have loved to see a small example with dataI also don't get the difference between
childrenanddescendantsunless you meandescendantsalso include grandchildren etc. I think you could find a better name thandescendants.
This
// create an index for(var index in model) { if (!model.hasOwnProperty(index)) { continue; } this.index[model[index].right] = index; }could be
// create an index for(var index in model) { if (model.hasOwnProperty(index)) { this.index[model[index].right] = index; } }by avoiding the
continuestatementThis
try { var node = new NestedSetModelNode(model[entry], model, this.index); this.model.push(node); } catch(e) {}intrigues me, I don't see what could go wrong with this code that you need a
try/catch, even more intriguing is that you fail silently here, potentially providing wrong query results later in the gameThis part could be faster for strict comparisons:
for (var i = 0; i <= keys[1].length; i++) { var prop = keys[1][i]; if (a[prop] !== b[prop]) { return false; } } if (!strict) { return true; } for (var prop in keys[0]) { if (b[prop] !== undefined && a[prop] !== b[prop]) { return false; } if (typeof a[prop] === 'object' && this.compareNodes(a[prop], b[prop], true) === false) { return false } }What you do here every time you check for strict comparison is comparing
bwithausing!=and then again comparingawithbusing!==. Since you know for strict comparison that the key count is the same, this is overkill. Furthermore I have doubts on(b[prop] !== undefined && a[prop] !== b[prop])if the value ofb[prop]isundefinedand the value of a[prop] is notundefined, then the comparison should be false. Furthermore I am not sure why youthis.compareNodesin case of an object, ifa[prop] === b[prop], then the nodes cannot be different because it is the same object (as I understand it), if you want to really compare two different objects for the same properties, then that should should be before the!==check.I would counter propose something like this:
if (!strict) { for (var prop in keys[1]) { //I still wonder, why 1, not 0? if (b[prop] != a[prop]) { return false; } } } else { for (var prop in keys[0]) { if (typeof a[prop] == 'object') { if( !this.compareNodes(a[prop], b[prop], true)) { return false; } } else if (a[prop] !== b[prop]) { return false; } } } //We made it thru, a and b are equal (enough) return true;Perhaps consider renaming
NestedSetModel.prototype.findtofindFirst, since it only returns the first matchThis
var self = this; Object.keys(node).forEach(function(prop) { self[prop] = node[prop]; });only needs
selfbecause of the forEach, from a style/performance perspective you could avoid this by going to a fasterforloop.This
this.model.map(function(node) { if (self.left > node.left && self.right < node.right) { parents.push(new NestedSetModelNode(node, self.model, self.index)); } });utilizes
mapwhich builds an array for you, if you are not going to use the results ofmap, then you should useforEach, and since you are interested in speed, you should use a simpleforloop.On the whole I dont get your data structur with
leftandright, I would have loved to see a small example with dataI also don't get the difference between
childrenanddescendantsunless you meandescendantsalso include grandchildren etc. I think you could find a better name thandescendants.An excellent point of @Megawac, which I completely missed is that using
for .. inis considered very bad practice for arrays. If you simply use the regularforloop then that will be faster because you no longer need checkhasOwnPropertyevery single time.
Interesting code,
the first thing that comes to mind is that forEachand map are slower than for loops, so you might want to consider converting those statements to for loops.
the second thing is that I assume you query several times these data structures, if that is the case then the node should know who is/are the parents and who is/are the children, it does not make sense to traverse (partially) the model every time to figure that out.
Other than that
This
// create an index for(var index in model) { if (!model.hasOwnProperty(index)) { continue; } this.index[model[index].right] = index; }could be
// create an index for(var index in model) { if (model.hasOwnProperty(index)) { this.index[model[index].right] = index; } }by avoiding the
continuestatementThis
try { var node = new NestedSetModelNode(model[entry], model, this.index); this.model.push(node); } catch(e) {}intrigues me, I don't see what could go wrong with this code that you need a
try/catch, even more intriguing is that you fail silently here, potentially providing wrong query results later in the gameThis part could be faster for strict comparisons:
for (var i = 0; i <= keys[1].length; i++) { var prop = keys[1][i]; if (a[prop] !== b[prop]) { return false; } } if (!strict) { return true; } for (var prop in keys[0]) { if (b[prop] !== undefined && a[prop] !== b[prop]) { return false; } if (typeof a[prop] === 'object' && this.compareNodes(a[prop], b[prop], true) === false) { return false } }What you do here every time you check for strict comparison is comparing
bwithausing!=and then again comparingawithbusing!==. Since you know for strict comparison that the key count is the same, this is overkill. Furthermore I have doubts on(b[prop] !== undefined && a[prop] !== b[prop])if the value ofb[prop]isundefinedand the value of a[prop] is notundefined, then the comparison should be false. Furthermore I am not sure why youthis.compareNodesin case of an object, ifa[prop] === b[prop], then the nodes cannot be different because it is the same object (as I understand it), if you want to really compare two different objects for the same properties, then that should should be before the!==check.I would counter propose something like this:
if (!strict) { for (var prop in keys[1]) { //I still wonder, why 1, not 0? if (b[prop] != a[prop]) { return false; } } } else { for (var prop in keys[0]) { if (typeof a[prop] == 'object') { if( !this.compareNodes(a[prop], b[prop], true)) { return false; } } else if (a[prop] !== b[prop]) { return false; } } } //We made it thru, a and b are equal (enough) return true;Perhaps consider renaming
NestedSetModel.prototype.findtofindFirst, since it only returns the first matchThis
var self = this; Object.keys(node).forEach(function(prop) { self[prop] = node[prop]; });only needs
selfbecause of the forEach, from a style/performance perspective you could avoid this by going to a fasterforloop.This
this.model.map(function(node) { if (self.left > node.left && self.right < node.right) { parents.push(new NestedSetModelNode(node, self.model, self.index)); } });utilizes
mapwhich builds an array for you, if you are not going to use the results ofmap, then you should useforEach, and since you are interested in speed, you should use a simpleforloop.On the whole I dont get your data structur with
leftandright, I would have loved to see a small example with dataI also don't get the difference between
childrenanddescendantsunless you meandescendantsalso include grandchildren etc. I think you could find a better name thandescendants.