web-dev-qa-db-ja.com

配列の配列内の同じインデックスにある要素を1つの配列に合計する方法は?

次のような配列の配列があるとしましょう。

[
  [0, 1, 3],
  [2, 4, 6],
  [5, 5, 7],
  [10, 0, 3]
]

Javascriptの内部配列の各位置にあるすべての値を合計する新しい配列を生成するにはどうすればよいですか?この場合、結果は[17、10、19]になります。内部配列の長さに関係なく機能するソリューションを用意する必要があります。これは、mapとfor-ofの組み合わせ、または場合によってはreduceを使用して可能だと思いますが、頭を完全に包むことはできません。検索しましたが、これに完全に一致する例は見つかりませんでした。

16
hmlee

Array.prototype.reduce()Array.prototype.forEach() と組み合わせて使用​​できます。

var array = [
        [0, 1, 3],
        [2, 4, 6],
        [5, 5, 7],
        [10, 0, 3]
    ],
    result = array.reduce(function (r, a) {
        a.forEach(function (b, i) {
            r[i] = (r[i] || 0) + b;
        });
        return r;
    }, []);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

更新、配列を減らすためのマップを取ることによるより短いアプローチ。

var array = [[0, 1, 3], [2, 4, 6], [5, 5, 7], [10, 0, 3]],
    result = array.reduce((r, a) => a.map((b, i) => (r[i] || 0) + b), []);
    
console.log(result);
47
Nina Scholz

使用 Lodash 4

_function sum_columns(data) {
  return _.map(_.unzip(data), _.sum);
}

var result = sum_columns([
  [1, 2],
  [4, 8, 16],
  [32]
]);

console.log(JSON.stringify(result));_
_<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>_

古いLodashバージョンといくつかのコメント

Lodash 4は__.unzipWith_の動作方法を変更し、iterateeはすべての値をspread引数として一度に取得するため、レデューサースタイル__.add_を使用できなくなりました。 Lodash の場合、次の例は問題なく機能します。

_function sum_columns(data) {
  return _.unzipWith(data, _.add);
}

var result = sum_columns([
  [1, 2],
  [4, 8, 16],
  [32],
]);

console.log(JSON.stringify(result));_
_<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>_

__.unzipWith_は、行が他の行より短い場所にundefinedsを挿入し、__.sum_は未定義の値を0として扱います。(Lodash3以降)

入力データにundefinedおよびnullアイテムを含めることができ、それらを0として扱いたい場合は、次を使用できます。

_function sum_columns_safe(data) {
  return _.map(_.unzip(data), _.sum);
}

function sum_columns(data) {
  return _.unzipWith(data, _.add);
}

console.log(sum_columns_safe([[undefined]])); // [0]
console.log(sum_columns([[undefined]]));      // [undefined]_
_<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>_

このスニペットはLodash3で動作しますが、残念ながら、Lodash 4でundefinedを0として扱う良い方法は見つかりませんでした。現在、合計が変更されているため、_.sum([undefined]) === undefined

9
Tamas Hegedus

ES6のワンライナー、mapおよびreduce

var a = [ [0, 1, 3], [2, 4, 6], [5, 5, 7], [10, 0, 3] ];

var sum = a[0].map((_, i) => a.reduce((p, _, j) => p + a[j][i], 0));

document.write(sum);
5
isvforall

示されているように、配列が静的であると仮定します。

a = [
      [0, 1, 3],
      [2, 4, 6],
      [5, 5, 7],
      [10, 0, 3]
    ]

b = []
        
for(i = 0; i < a[0].length; i++){                                            
  count = 0
  for(j = 0; j < a.length; j++){                             
     count += a[j][i]                   
   }
   b.Push(count)
}               
console.log(b)
0
Abhishek Gurjar

ネストされた配列の長さが常に同じであると仮定すると、concatとreduceを使用できます。

    function totalIt (arr) {
        var lng = arr[0].length;
       return [].concat.apply([],arr)  //flatten the array
                .reduce( function(arr, val, ind){ //loop over and create a new array
                    var i = ind%lng;  //get the column
                    arr[i] = (arr[i] || 0) + val; //update total for column
                    return arr;  //return the updated array
                }, []);  //the new array used by reduce
    }
    
    var arr = [
      [0, 1, 3],
      [2, 4, 6],
      [5, 5, 7],
      [10, 0, 3]
    ];
    console.log(totalIt(arr));  //[17, 10, 19]
0
epascarello