Reputation: 63
I have an array like this:
abcArr = [["A", "dog", 10], ["B", "cat", 20], ["A", "dog", 30],["C", "pig", 40]] ["A", "cat", 30], ["B", "cat", 20], ["A", "horse", 10];
I was looking at this post (jquery array group by) and I need something similar for my issue but I need to group my array based on 2 elements.
So my answer should look like this:
[["A", "dog", 40], ["B", "cat", 40], ["C", "pig", 40]] ["A", "cat", 30], ["A", "horse", 10];
I tried @jfriend00 's .each()
approach to group just one field and it works, but I don't know how to adapt it to use two fields to group the data above.
abcArr = [["A", 10],["B", 20],["A", 30],["C", 40]];
var items = {},
base, key;
$.each(abcArr, function(index, val) {
key = val[0];
if (!items[key]) {
items[key] = 0;
}
items[key] += val[1];
});
var outputArr = [];
$.each(items, function(key, val) {
outputArr.push([key, val]);
});
console.log(outputArr);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Thanks.
Upvotes: 2
Views: 2379
Reputation: 11116
What you can do is, instead of one field being used as the key for your items
object, you can combine multiple keys, like so:
Note - jQuery is not necessary to solve this issue because JavaScript has the handy .reduce()
and .map()
functions built right in.
var abcArr = [["A", "dog", 10], ["B", "cat", 20], ["A", "dog", 30],["C", "pig", 40], ["A", "cat", 30], ["B", "cat", 20], ["A", "horse", 10]];
// group the items by letter-animal and sum the results
var items = abcArr.reduce(function (results, current) {
var letter = current[0];
var animal = current[1];
var value = current[2];
// combine the two fields as the key to match on.. this is where the magic happens
var key = letter + "-" + animal;
if (!results[key]) {
results[key] = 0;
}
results[key] += value;
return results;
}, {});
// break the keys out from the hyphenated form back into individual array elements w/ value
var outputArr = Object.keys(items).map(function (key) {
var splitKey = key.split("-");
var letter = splitKey[0];
var animal = splitKey[1];
var itemValue = items[key];
return [letter, animal, itemValue];
});
console.log(outputArr);
Alternatively with ES6 Syntax:
var abcArr = [["A", "dog", 10], ["B", "cat", 20], ["A", "dog", 30],["C", "pig", 40], ["A", "cat", 30], ["B", "cat", 20], ["A", "horse", 10]];
var items = abcArr.reduce((results, [letter, animal, value]) => {
var key = letter + "-" + animal;
if (!results[key]) {
results[key] = 0;
}
results[key] += value;
return results;
}, {});
var outputArr = Object.keys(items).map(key => [...key.split("-"), items[key]]);
console.log(outputArr);
Upvotes: 1