Problem
I wrote a JavaScript source which regrouping by new key i.e. following JSON to the other:
{
"items" : [
{
"company" : "A"
, "name" : "Prod_A01"
}
, {
"company" : "A"
, "name" : "Prod_A02"
}
, {
"company" : "B"
, "name" : "Prod_B01"
}
]
}
to:
{
"A" : [
{
"company" : "A"
, "name" : "Prod_A01"
}
, {
"company" : "A"
, "name" : "Prod_A02"
}
]
, "B" : [
{
"company" : "B"
, "name" : "Prod_B01"
}
]
}
And here is logic:
function regroup(collection, key){
var novo_obj = {};
var type = typeof collection;
var keyGroup = [];
getKeyGroup(collection, key, keyGroup);
for(var i = 0; i < keyGroup.length; i++) {
novo_obj[keyGroup[i]] = [];
gatherElements(collection, key, keyGroup[i], novo_obj[keyGroup[i]]);
//console.log(novo_obj);
}
console.log(JSON.stringify(novo_obj));
return novo_obj;
}
function gatherElements(collection, key, value, arr){
//console.log(collection);
if(typeof collection == 'object'){
var targetValue = collection[key];
if(typeof targetValue != 'undefined' && targetValue == value){
arr.push(collection);
}else{
for(var elem in collection){
gatherElements(collection[elem], key, value, arr);
}
}
}else if(typeof collection == 'array'){
for(var i = 0; i < collection.length; i++) {
getKeyGroup(collection[i], key, value, arr);
}
}
}
function getKeyGroup(collection, key, keygroup){
var targetValue = '';
if(typeof collection == 'object'){
targetValue = collection[key];
if(typeof targetValue != 'undefined'){
keygroup.push(targetValue);
}else{
for(var elem in collection){
getKeyGroup(collection[elem], key, keygroup);
}
}
}else if(typeof collection == 'array'){
console.log('isArr');
for(var i = 0; i < collection.length; i++) {
getKeyGroup(collection[i], key, keygroup);
}
}
return keygroup;
}
function main(){
var test = {
items : [
{
company : "A"
, name : "Prod_A01"
}
, {
company : "A"
, name : "Prod_A02"
}
, {
company : "B"
, name : "Prod_B01"
}
]
}
regroup(test, "company");
}
However, I think looping every time does not look so good. I need to improve this source code.
Solution
I think you may be complicating things a lot. If I understand correctly you are basically after groupBy
which you can find in lodash, or implement in a few lines of code:
function groupBy(coll, f) {
return coll.reduce(function(acc, x) {
var k = f(x);
acc[k] = (acc[k] || []).concat(x);
return acc;
}, {});
}
var test = {
items: [{
company: "A", name: "Prod_A01"
}, {
company: "A", name: "Prod_A02"
}, {
company: "B", name: "Prod_B01"
}]
};
var result = groupBy(test.items, function(x){return x.company});
JSON.stringify(result);
/*^
{
"A": [
{
"company": "A",
"name": "Prod_A01"
},
{
"company": "A",
"name": "Prod_A02"
}
],
"B": [
{
"company": "B",
"name": "Prod_B01"
}
]
}
*/
You can use this to group a collection (array of objects) by some property, test.items
in this case. Also, I would leave the JSON part out of it, because it is irrelevant to the grouping algorithm.