TDmoneybanks
TDmoneybanks

Reputation: 518

How would you count the instances of objects in arrays within an array

So, essentially I am getting a set of records as an array of objects like

[{name: tyler, categories: ["friends", "neighbor"]}, {name: joe, categories: ["friends"]}]. 

and I want to count the contents of the internal array instances. So in this example, the return would be friends: 2 and neighbor: 1. As some background info, I am getting a collection of records from mongo within the meteor framework. I am then using fetch() to convert these records to an array of objects like above. I then want to use these objects to create a pie graph based on the counts of the specific instances of each object within the inner array of each object (these objects would be the ones returned by the db query) within the outer array.

Upvotes: 1

Views: 1257

Answers (3)

saimeunt
saimeunt

Reputation: 22696

You can write a simple function to count your categories counts and store the result in a dictionary of key/value pairs.

function countCategories(docs){
  // accumulate results inside a JS object acting as a key/value dict
  var result = {};
  docs.forEach(function(doc){
    doc.categories.forEach(function(category){
      // initialize count to 0 when a new key is found
      if(_.isUndefined(result[category])){
        result[category] = 0;
      }
      // increment the corresponding count
      result[category]++;
    });
  });
  return result;
}

Given the sample data in your question, this function will return :

Object {friends: 2, neighbor: 1}

EDIT :

You can then convert this dictionary to an array of objects.

function convertToArray(dict){
  var result = [];
  _.each(dict, function(value, key){
    var object = {
      category: key,
      count: value
    };
    result.push(object);
  });
  return result;
}

Upvotes: 1

bjelli
bjelli

Reputation: 10090

Using underscore and reduce:

result = _.reduce( data, function( counter, o ) {
    _.each( o.categories, function(c){
        counter[c] = 1 + _.result(counter, c, 0);
    });
    return counter;
}, {});

Demo in this fiddle

reduce goes through your array (first arg) and applies the function you give it (second arg) and a starting value for the memo (third arg). This memo is passed to each call to your function as the first argument, you can us it to store stuff you want to remember.

I've set the starting value for the memo to be an empty object which we will use as a counter.

result = _.reduce( data, function( counter, o ) {
    // current element of the array: o
    // stuff you want to remember for: counter
    return counter; 
}, {});

Upvotes: 1

Azura
Azura

Reputation: 86

You might attach a function to the array and count the elements inside of it.

yourArray = [1,2,3];

yourArray.countElements = function(){ 
  var elements=0; 
  for(x=0;this[x]!=undefined;x++){ 
    instances++ 
  } 
  return instances; 
};

yourArray.countElements(); // outputs 3

Modify this, using "neighbors" and "friends" instead of "elements" and counting them only if this["categories"]["the_category"] is different of undefined.

Also you could attach it to Array.prototype

Upvotes: 0

Related Questions