2

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.

5
  • 1
    @NewBee Can you please edit your post and include the code there? Commented Feb 27, 2018 at 20:49
  • I have tried @friend00 's .each approach. Code is included in the post. Commented Feb 27, 2018 at 21:03
  • The abcArr in the top example doesn't match the one in the runnable snipplet. Commented Feb 27, 2018 at 21:05
  • @NewBee Take a look at my solution and see if that's what you're looking for Commented Feb 27, 2018 at 21:06
  • @Taplar The working example only groups by 1 field, OP's new use case requires grouping by 2 fields and doesn't know how to bridge the gap between the working solution and what they need. Commented Feb 27, 2018 at 21:08

1 Answer 1

1

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);

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

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.