0

I have an array of json objects who results I want to groupBy() based on multiple properties i.e.,

I have:

[
  {
     prop1:val1,
     prop2:val2,
     prop3:val3,
     prop4:val4
  }
]

Now if I just wanted to group by prop1 I guess I could have done :

_.groupBy(givenArray, 'prop1');

Now what should I do if I have to group by prop1,prop2 and prop3, i.e., (prop1 && prop2 && prop3)

Please guide.

2 Answers 2

1

You can put that target values to an array, and then form them to string, or just transform them to string form and combine:

_.groupBy(givenArray, function(item) {
   var keys = _.pick(item, 'prop1', 'prop2', 'prop3');
   // If all are string or number,
   // return keys.join('_@%@_'); // this prevent ['ab', 'a'] generate same key to ['a', 'ba'];
   return JSON.stringify(keys);
});

JSON.stringify maybe one of the many ways to create a combined key, I'm not sure what your vals is (string, number or else), so I'll just use stringify here.

Sign up to request clarification or add additional context in comments.

Comments

1

It really depends on what you want your final structure to be.

If you don't mind a non-flat object structure, you can do nested _.groupBy calls:

var result = _(givenArray) //begin chain
.groupBy('a')
.mapValues(function(groupedByA) {
     return _(groupedByA) //begin chain
    .groupBy('b')
    .mapValues(function (groupedByAAndB) {
        return _.groupBy(groupedByAAndB, 'c');
    })
    .value(); //end chain
})
.value(); //end chain
//Then you can do things like:
result[5][4][3]; //All items where a=5, b=4, and c=3.

Downside here is that there's an extra level of nesting for each property you group by, and result[5][4] will blow up if there aren't any results where a=5 for example. (Though you could use a library like koalaesce for that)

Alternatively, if you want a flat object structure, but don't mind it being a bit ungainly to access the items, then:

var result = _.groupBy(givenArray, function (item) {
    return JSON.stringify(_.pick(item, 'a','b','c'));
});

//Much simpler above, but accessed like: 
result[JSON.stringify({a: 5, b:4, c:3})]

Much simpler and scales better to grouping by more things... but awkward to work with, since the keys are full JSON strings; but then you also don't have the null issue that the first option has.

You can also, just use _.values or some equivalent to turn the flat object structure into a single array of arrays. Then there's obviously no "random" access to get all items with a given value of a,b, and c, but you can always loop over it.

Comments

Your Answer

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.