Follow me if you want to grow your full-stack JavaScript skills with my screencasts and courses.

lo-dash mixins

The data

Let's have a look at our data we'll be working on. We've got an array with a bunch of sales transactions in it. Each sale has a product and a quanitity associated to it. What we wanna do is total up the number of sales for each product.

app.js
  
  var sales = [
      {
          product: 'iphone',
          quantity: 5,
          date: new Date()
      },
      {
          product: 'nexus',
          quantity: 1,
          date: new Date()
      },
      {
          product: 'iphone',
          quantity: 2,
          date: new Date()
      },
      {
          product: 'nokia',
          quantity: 1,
          date: new Date()
      },
      {
          product: 'nexus',
          quantity: 4,
          date: new Date()
      },
  ];

  

Sum with _.reduce

Before we go the mixin route, let's sum up the values first. Usually if you want to sum up items array, you would use reduce. I use the lodash reduce function, even though we could've used the native ES5 implementation. Lo-dash's functions are often more performant than native implementations, so it's good to use it once you've pulled it in for both performance and consistency reasons.

To reduce, we pass 3 values. First the array containing the items we want to add up, a function containing the logic for the reduce operation, and lastly the starting value for our calculation, in our case an empty object. If you wanted to add onto an existing calculation, for example a previous period's sale totals, you could have passed that in here.

In our reduce logic, if it doesn't exist, we add an attribute onto the result with the current sale's product as the key, and set it to 0. We then increment this attribute's value with the current sale's quantity attribute. Lastly we return the result, so that the reduce operation can add the next item to it. Let's have a look at the result. Great, it worked.

app.js
  
  var _ = require('lodash');

  var summed = _(sales)
      .chain()
      .reduce(function(result, sale) {
          result[sale.product]  = result[sale.product] || 0 ;
          result[sale.product] += sale.quantity;
          return result;
      }, {})
      .value();

  console.log(summed);
  

When we run this, we get the following:

output
  
  { iphone: 7, nexus: 5, nokia: 1 }
  [Finished in 0.2s]

  

Make it generic

Now that we've got our summing logic down, we extract it to a function, and make it a bit more generic. We put this reduce logic on the clipboard, and paste it into a function called sum, this function should return the result.

We make this logic generic by adding parameters to our function. First we parameterize the array that it should process. Now we add key and value parameters.

Instead of hardcoding the product attribute here, we use the parameter to dynamically get the value we want to group by from the object. And we do the same for the value we want to total up.

We change our logic to call our generic function, passing in the correct parameters. The sales array, we want totals for products, and the totals should contain the quanity of each sale.

app.js
  
  function sum(arr, key, val){
      return _.reduce(arr, function(result, item){
          result[item[key]] = result[item[key]] || 0;
          result[item[key]] += item[val];
          return result;
      }, {});
  }


  var summed = sum(sales, 'product', 'quantity');

  console.log(summed);

  

Making it a mixin

And now for the long awaited mixin part, which is simple now that we've refactored our code to use a generic function. To do this we use the mixin function of lodash, which takes an object with a kry for each mixin we want to add, in our case we only want to add sum.

We change our code at the bottom here to use the mixin, and... it works!

app.js
  
  function sum(arr, key, val){
      return _.reduce(arr, function(result, item){
          result[item[key]] = result[item[key]] || 0;
          result[item[key]] += item[val];
          return result;
      }, {});
  }

  _.mixin({
      sum: sum
  });

  var summed = _.sum(sales, 'product', 'quantity')

  console.log(summed);
  

Wrap up

Hopefully you've seen how easy it is to extend lo-dash!