Reputation: 1505
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?
Upvotes: 0
Views: 2603
Reputation: 16726
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.
Upvotes: 1
Reputation: 4614
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/
Upvotes: 2