2017-06-06 3 views
3

私は同じ長さの2つの配列を持っているので、私はどうにかそれらを両方とも同時にreduceメソッドで処理したいと思います。ような何か:array.prototype.reduce()を使用して2つの配列を同時に処理できますか?

var arr1 = [2, 3, 4, 5, 6]; 
var arr2 = [5, 10, 4, 9, 5]; 
var productSum = arr1.reduce(function(sumOfProducts, item, secondArrayItem) { 
    /* here I would like to multiply item from arr1 by the item from arr2 at the same index */ 
    return sumOfProducts + item * secondArrayItem; 
}, 0, arr2) 
console.log(productSum); // 131 

オプションはもちろんcurrentIndexを使用してarr2から正しい項目にアクセスすることですが、私は、関数のスコープ外の変数にアクセスしていますように、その解決策は醜いです。

具体的な使用例は、var resources = [2, 5, 4, 6, 2]のようなリソースを持つ配列を持っており、各項目がvar cost = [3, 1, 0, 0, 1]のような別の配列の対応するリソースコストより高いかどうかをチェックしたいと考えています。

reduce()機能を使用すると、これに対していくつかの素晴らしい解決策がありますか?

+2

通常は、2つのリストをまとめて圧縮し、次に圧縮したリストを縮小します。しかし、JSのリストをいかにイディオム的に圧縮するかはわかりません。 – Carcigenicate

+4

"*その解決策は、関数の範囲外の変数にアクセスしているので醜いです。*" - 私はそれについて醜いものは見当たりません。グローバルにアクセスしたり、クロージャを使ったりするとき、これを常に行います。重要なことは、変数が一定であることだけです。この解決法について本当に醜いのは、a)対称ではなく(arr1がarr2にアクセスするのとは異なる動作をする)、b)配列の長さが同じであることを保証しなかったため、arr2 [i] 'は有効なインデックスにアクセスします。 – Bergi

答えて

1

私はこれを行うには知っている標準的な方法は、(「ビュン」)に対応するペアのリストに2つのリストを組み合わせることで、その後、組み合わせリストを減らす:zipの実装で

var zipped = zip(arr1, arr2) 

reduce((acc, [x, y]) => (Use x and y), 
       zipped) 

を参照してくださいあなたが最初の二つのリストを圧縮し、それを軽減し、配列の要素を抽出し、それらを渡すために非構造を使用することができますRamdaを使用this question.

(私はトランジットの降りたときの構文を確認します)

+0

これは、巨大な配列でさえも行く方法ですか?私はちょうど両方の配列の値を一度に繰り返したいときに、新しい配列全体を作成したくありません。 – BoltKey

+3

@BoltKey巨大な配列を扱うには、 'reduce'を忘れて単純なforループを使用する必要があります。 –

+1

@BoltKeyこれは、遅延構造を扱う際にはるかに良いアプローチですが、私は認めます。それは、1つの反復処理が必要となり、次に別の反復処理が必要になり、中間のリストが作成されるため、残念なことにパフォーマンスが低下します。 – Carcigenicate

2

コールバックの引数として:

const reduceTwo = (callback, initialValue, arr1, arr2) => 
 
    R.reduce((acc, [x, y]) => callback(acc, x, y), initialValue, R.zip(arr1, arr2)); 
 

 
const arr1 = [2, 3, 4, 5, 6]; 
 
const arr2 = [5, 10, 4, 9, 5]; 
 
console.log(reduceTwo((acc, x, y) => acc + x * y, 0, arr1, arr2));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.24.1/ramda.min.js"></script>

+2

ジッパー機能のためだけにライブラリ全体を使用すると、少し冗長に見えます... – BoltKey

+0

@BoltKeyなぜですか?あなたのコードをバンドルするためにtree shakingでwebpackを使用しても、パフォーマンスに悪影響はありません。 –

0

純粋なJSで次のようにあなたが行うことができます。

var arr1 = [2, 3, 4, 5, 6], 
 
    arr2 = [5, 10, 4, 9, 5], 
 
    result = arr1.reduce((r,c,i) => (r.sum = r.sum ? r.sum + c * r[i] : c * r[i], r), arr2.slice()).sum; 
 
console.log(result);

私あなたが後でかなarr2for inループを適用しない場合は、まだあなたはまだスライスなしで行うことが状態変数とそれを変異させないために.slice()arr2 ...

関連する問題