i have array of objects, ones:
{ "short_id": "2p45q", "path": "/", "name": { "en-us": "industrialdesign" } } ... { "short_id": "2q56r", "path": "/2p45q/", "name": { "en-us": "automotive" } } i must iterate on each element of array , check path, find parent of element , push in new array property of parent called sub. each child can have sub property on it's own, being parent of more children. final result (for example) like:
{ "short_id": "2p45q", "path": "/", "name": { "en-us": "test a" }, "sub": [ { "short_id": "2q56r", "path": "/2p45q/", "name": { "en-us": "test a.1" } } ] } i have working code (using this jsonpath lib):
function(categories) { var _categories = []; angular.foreach(angular.copy(categories), function(_category) { if (_category.path === "/") { _categories.push(_category); } else { var _path = _category.path.split("/"); _path.pop(); var _parent = _path.pop(); jsonpath.apply(_categories, "$..[?(@.short_id=='" + _parent + "')]", function(obj) { if(!obj.hasownproperty("sub")) { obj.sub = []; } obj.sub.push(_category); return obj; }); } }); return _categories; } but performance bad, because i'm querying entire array each iteration.
my question how can optimize code?
notes:
- each
short_id5 characters long. - each character in
short_idcan[0-9a-z] pathguaranteed start , end/
create tmp object hashmap, can use path , id create new key store.
logic :
if path
'/', root, put_categoriesarray.if not, check if target parent exist in hashstore or not, if not, create fake one, , put self target
subattr.for element, create key
_category.path + _category.short_id + '/', , check if exist in hashstore, if exist, 1 in store should fake,subfake. assign hashstore created key.
use key decide whether object exist in map or not should o(1). performance of function should o(n) while n number of element in origin list.
function buildtree(categories) { var _categories = []; var store = {}; angular.foreach(angular.copy(categories), function(_category) { if (_category.path === '/') { _categories.push(_category); } else { var target; // if parent exist if (typeof store[_category.path] !== 'undefined') { // check parent have sub or not, if not, create one. target = store[_category.path]; if (typeof store[_category.path].sub === 'undefined') { target.sub = []; } } else { // create fake parent. target = {sub: []}; store[_category.path] = target; } // push parent's sub target.sub.push(_category); } // create key map var key = _category.path + _category.short_id + '/'; // if fake object exist, sub; if (typeof store[key] !== 'undefined') { _category.sub = store[key].sub; } store[key] = _category; }); return _categories; }
Comments
Post a Comment