How to group by an array of numbers?

I know how to do this in SQL lol, but not in JS.

If you have an array like this = var arrayRepeatedNumbers = [100,100, 20, 10,10,10]

How can you group them by amount?

Example:

var arrayNonRepeated = [Hundreds: 2, Twenties: 1, Tens: 3]

The above is not an array. I assume you meant to create an object from the array like:

var objGroupedValues = {Hundreds: 2, Twenties: 1, Tens: 3}

First, you would need have some way of defining that 100 is related to ‘Hundreds’, 20 is related to ‘Twenties’, and 10 is related to ‘Tens’. I think the easiest way is to use a lookup object.

var lookupGroups = {
  100: 'Hundreds',
  20: 'Twenties',
  10: 'Tens'
};

Then, you would just would created an empty objGroupedValues to be used to collect the counts of each number…

var objGroupedValues  = { };

Now, you will need to iterate through the arrayRepeatedNumbers with your favorite iteration method. I will just a plain old for loop. During each iteration, you will get the string name of the number from the lookupGroups object. Then, you will check if objGroupedValues contains a property with this string name. If it does, then you increment the property’s value by one. If not, then you add the property and assign it a value of 1.

for (var i = 0; i < arrayRepeatedNumbers.length; i++) {
  var currentNum = arrayRepeatedNumbers[i];
  var numName = lookupGroups[currentNum]; // gets the string name of the current number
  if (objGroupedValues[numName]) { // does this number exist yet in objGroupedValues?
   objGroupedValues[numName]++; // it does, so increment the count by 1
  } else {
   objGroupedValues[numName] = 1; // it does not, start the count at 1
  }
}

console.log(objGroupedValues); // { Hundreds: 2, Twenties: 1, Tens: 3 }

This is not the only way to do this, but just came up with it off the top of my head.

EDIT: A slightly more compact version of the same general logic using reduce is below:

var arrayRepeatedNumbers = [100,100, 20, 10,10,10];

var lookupGroups = {
  100: 'Hundreds',
  20: 'Twenties',
  10: 'Tens'
};

var objGroupedValues = arrayRepeatedNumbers.reduce((countsObj, num) => {
  var numName = lookupGroups[num];
  countsObj[numName] = countsObj[numName]
    ? countsObj[numName] + 1
    : 1;
  return countsObj;
}, {});

console.log(objGroupedValues); // { Hundreds: 2, Twenties: 1, Tens: 3 }
(() => {

// add definitions in here.
const dictionary = new Map([
    [10, 'Tens'],
    [20, 'Twenties'],
    [100, 'Hundreds']
]);

// your test values
const arrayRepeatedNumbers = [
    100, 100, 20, 10, 10
];

// will hold a map of repeating values
const mapNonRepeated = new Map();

arrayRepeatedNumbers.forEach((number) => {

   // stores dictionary key
   const dictionaryKey = dictionary.get(number);
   
   // checks if key exists in your final map
   const keyExists = mapNonRepeated.has(dictionaryKey);

   // if key exists in map add one to it
   if (keyExists){
       let value = mapNonRepeated.get(dictionaryKey);
       mapNonRepeated.set(dictionaryKey, value = value + 1);
       return;
   }

   // otherwise set it to 1
   mapNonRepeated.set(dictionaryKey, 1);
});

console.log(mapNonRepeated);
//Map(3) {"Hundreds" => 2, "Twenties" => 1, "Tens" => 2}

// Map has some advantages over the standard Object.

})();
1 Like