2
\$\begingroup\$

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.

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Apr 2, 2016 at 5:16
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

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.

answered Apr 2, 2016 at 5:29
\$\endgroup\$
3
  • \$\begingroup\$ wow. awesome! so simple!! \$\endgroup\$ Commented Apr 2, 2016 at 6:02
  • \$\begingroup\$ Got one more question. You mentioned about lodash. Why did you mentioned that? (Your code seems work nicely with native js) \$\endgroup\$ Commented Apr 2, 2016 at 6:05
  • \$\begingroup\$ Just because it is a popular library, you may use it and import only that function npmjs.com/package/lodash.groupby. Also in lodash it is a bit more flexible, you can do _.groupBy(test.items, 'company') \$\endgroup\$ Commented Apr 2, 2016 at 6:19

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.