javascript - Given an array of objects how do I sort the objects by a property in depth n -
i have array of objects wish sort grouping property data , string telling me property group by(eg: 'organization' or 'organization.name')
i need write function takes in data looks beforedata
, returns afterdata
input :
beforedata = [ {'name':'john doe', 'id':1, 'organizations':[{'id':12, 'longname': 'group a'},{'id':13, 'longname': 'group b'}]}, {'name':'foobar', 'id':2, 'organizations':[{'id':13, 'longname': 'group b'},{'id':14, 'longname': 'group c'}]}, {'name':'kristine bell', 'id':3, 'organizations':[{'id':12, 'longname': 'group a'}]}, {'name':'adrian p', 'id':4, 'organizations':[{'id':12, 'longname': 'group a'}]} ]
output:
afterdata = [ { 'group': 'group a', 'entities':[ {'name':'adrian p', 'id':4, 'organizations':[{'id':12, 'longname': 'group a'}]}, {'name':'kristine bell', 'id':3, 'organizations':[{'id':12, 'longname': 'group a'}]}, {'name':'john doe', 'id':1, 'organizations':[{'id':12, 'longname': 'group a'},{'id':13, 'longname': 'group b'}]}] }, { 'group': 'group b', 'entities':[ {'name':'john doe', 'id':1, 'organizations':[{'id':12, 'longname': 'group a'},{'id':13, 'longname': 'group b'}]}, {'name':'foobar', 'id':2, 'organizations':[{'id':13, 'longname': 'group b'},{'id':13, 'longname': 'group c'}]},] }, { 'group': 'group c', 'entities':[ {'name':'foobar', 'id':2, 'organizations':[{'id':13, 'longname': 'group b'},{'id':13, 'longname': 'group c'}]},] } ]
how go accomplishing this? current attempts extremely bloated , take forever given large sets of data.
special kicker! : function solves issue needs able solve without knowing beforehand whether "group by property" in depth 1 or 2(eg: 'organization' or 'organization.longname').
something me:
// function performs data extraction object // first argument name of property extracted // might 1st level deep value `name` // or nested `foo.bar.baz` // in case if 1 of intermediate items array - array of // results returned function dot(name, obj) { if (!name) { return obj; } var match = name.match(/^([^.]+)(?:\.(.*))?$/), head = match[1], tail = match[2]; if (array.isarray(obj)) { return obj.map(function(item) { return dot(name, item); }); } if (obj === null || typeof obj != 'object') { return null; } return dot(tail, obj[head]); } // function accepts array of data , key group // result returns object keys equal group key // , values hold key function groupby(data, key) { return data.reduce(function(result, item) { var keys = dot(key, item); if (!array.isarray(keys)) { keys = [keys]; } keys.foreach(function(key) { if (!(key in result)) { result[key] = []; } result[key].push(item); }); return result; }, {}); } console.log(groupby(beforedata, 'organizations.longname'));
jsfiddle: http://jsfiddle.net/w8n4j/
it can reformatted other format want.
eg exact format question here tiny transformer:
function transformerexample(hash) { var result = []; (var key in hash) if (hash.hasownproperty(key)) { result.push({ group: key, entities: hash[key] }); } return result; }
ps: main implementation may not handle possible errors. depending on actual requirements not hard improve it.
Comments
Post a Comment