javascript - Convert an array of objects into a nested array of objects based on string property? -


i stuck on problem trying convert flat array of objects nested array of objects based name property.

what best way convert input array resemble structure of desiredoutput array?

var input = [     {          name: 'foo',          url: '/somewhere1',         templateurl: 'foo.tpl.html',         title: 'title a',          subtitle: 'description a'      },     {          name: 'foo.bar',          url: '/somewhere2',          templateurl: 'anotherpage.tpl.html',          title: 'title b',          subtitle: 'description b'      },     {          name: 'buzz.fizz',         url: '/another/place',         templateurl: 'hello.tpl.html',           title: 'title c',           subtitle: 'description c'      },     {          name: 'foo.hello.world',          url: '/',         templateurl: 'world.tpl.html',         title: 'title d',            subtitle: 'description d'      } ]  var desiredoutput = [     {         name: 'foo',         url: '/somewhere1',         templateurl: 'foo.tpl.html',         data: {             title: 'title a',             subtitle: 'description a'         },         children: [             {                 name: 'bar',                 url: '/somewhere2',                  templateurl: 'anotherpage.tpl.html',                 data: {                     title: 'title b',                      subtitle: 'description b'                 }             },             {                 name: 'hello',                 data: {},                 children: [                     {                         name: 'world',                         url: '/',                         templateurl: 'world.tpl.html',                         data: {                             title: 'title d',                                subtitle: 'description d'                         }                     }                 ]             }         ]     },     {         name: 'buzz',         data: {},         children: [             {                 name: 'fizz',                 url: '/',                 templateurl: 'world.tpl.html',                 data: {                     title: 'title c',                        subtitle: 'description c'                 }             }         ]     } ] 

note order of objects in input array not guaranteed. code running in node.js environment , open using libraries such lodash achieve desired output.

any appreciated.

using lodash (because why on earth want manipulate complex data without utility library). here's the fiddle.

function formatroute(route) {     return _.merge(_.pick(route, ['url', 'templateurl']), {         name: route.name.split('.'),         data: _.pick(route, ['title', 'subtitle']),         children: []     }); }  function getnamelength(route) {     return route.name.length; }  function buildtree(tree, route) {     var path = _.slice(route.name, 0, -1);      insertatpath(tree, path, _.merge({}, route, {         name: _.last(route.name)     }));      return tree; }  function insertatpath(children, path, route) {     var head = _.first(path);      var match = _.find(children, function (child) {         return child.name === head;     });      if (path.length === 0) {         children.push(route);     }     else {         if (!match) {             match = {                 name: head,                 data: {},                 children: []             };             children.push(match);         }          insertatpath(match.children, _.rest(path), route);     } }   // map routes correct formats. var routes = _.sortby(_.map(input, formatroute), getnamelength);  // can reduce formatted array desired format. var out = _.reduce(routes, buildtree, []); 

it works reshaping initial input split names arrays , add data / children properties. reduces data on buildtree uses mutating function ( :( ) insert current item in reduce @ given path.

the strange if (!match) part makes sure missing segments added in if they're not explicitly specified in initial data set url etc.

the last 2 lines work should in little function, , jsdoc. it's shame didn't recursive, i'm relying on array mutation insert route object deep within tree.

should simple enough follow though.


Comments

Popular posts from this blog

How has firefox/gecko HTML+CSS rendering changed in version 38? -

javascript - Complex json ng-repeat -

jquery - Cloning of rows and columns from the old table into the new with colSpan and rowSpan -