Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.

Join them; it only takes a minute:

Sign up
Join the Stack Overflow community to:
  1. Ask programming questions
  2. Answer and help your peers
  3. Get recognized for your expertise

I have an multidimensional array like

var arr = [[1,2,3],[1,3,2],[1,1,1]];

and I would like to add up what would be a matrix column for each column into a new array. The result I am expect would be [3,6,6]. This is the solution I came up with

function compute(arr) {
    var X = _.reduce(arr, function(acc, j) {
        acc += j[0];
        return acc;
    },0);
    var Y = _.reduce(arr, function(acc, k) {
        acc += k[1];
        return acc;
    },0);
    var Z = _.reduce(arr, function(acc, l) {
        acc += l[2];
        return acc;
    },0);
    return [X,Y,Z];
}

It is working but seems redudent to have 3 reduce functions. I am looking for a cleaner, more functional, faster solution using lodash.

I was thinking maybe I could use the _.flatten function since you can pass it a function for each iteration but I can't seem to avoid all the looping. Any suggestions?

share|improve this question
    
base something off of a callback instead of an anon, so you can do return _.map([0,1,2], sumCounter); – dandavis Aug 25 '14 at 3:04
    
It seems LoDash doesn't have zipWith, too bad... – elclanrs Aug 25 '14 at 3:07
    
zipWith is exactly what I'm looking for. haha too bad. Should rewrite this in haskell :) – Ptrkcon Aug 25 '14 at 3:28
up vote 1 down vote accepted

a simple way using vanilla to avoid an inner anon:

var arr = [[1,2,3],[1,3,2],[1,1,1]];

function sum(a,b){return a+b;}
function pluck(a){return a[this];}


arr.map(function(a,b,c){
   return c.map(pluck,b).reduce(sum);
}); // == [3, 6, 6]

the same in underscore/lodash:

var arr = [[1,2,3],[1,3,2],[1,1,1]];   

function sum(a,b){return a+b;}

_.map(arr, function(a,b,c){
  return _.reduce(_.pluck(c, b), sum);
}); // == [3, 6, 6]

personally, i like the native chaining of the Array methods, so i don't have to balance parens, but either way works.

it nicer to use different low-level interchangeable parts than one big procedure so that you can reduce, re-use, and recycle your keystrokes as you find yourself needing to do almost the same thing again later.

share|improve this answer

You can declare a function inside your function that handles your index and your array:

function compute(arr) {

    var reduce = function (index) {
        return _.reduce(arr, function(acc, array) {
            acc += array[index];
            return acc;
        },0);
    }

    var X = reduce(0);
    var Y = reduce(1);
    var Z = reduce(2);

    return [X,Y,Z];
};

If you want to make it a bit shorter, you could also just to this:

function compute(arr) {
    var reduce = function (index) {
        return _.reduce(arr, function(acc, array) {
            acc += array[index];
            return acc;
        },0);
    }

    return [reduce(0), reduce(1), reduce(2)];
};

If you want to make it a even shorter, you could also just to this. This one is a bit more functional because you're passing in the function as an argument to _.map

function compute(arr) {
    var reduce = function (index) {
        return _.reduce(arr, function(acc, array) {
            acc += array[index];
            return acc;
        },0);
    }
    return _.map([0, 1, 2], reduce);
};

You can check out the result here: http://jsfiddle.net/thejsj/p33hmc8q/

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.