JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

JavaScriptで2つの配列の対応する値を比較して優勢を判定する方法

はじめに

JavaScriptでは、同じ長さの2つの配列を受け取り、対応する位置にある要素同士を比較して「どちらの配列が優勢か」を判定したいケースがあります。本記事では、そのような比較を行う関数をシンプルなコードで実装する方法を解説します。

前提となるデータ

まず、長さが同じ2つの数値配列を用意します。

const arr1 = [23, 67, 12, 87, 33, 56, 89, 34, 25];
const arr2 = [12, 60, 45, 54, 67, 84, 36, 73, 44];

要件

上記のような2つの配列を第1引数・第2引数として受け取るJavaScript関数を作成します。関数は各インデックスの要素同士を比較し、次のルールに従って結果を返します。

  • -1 … 第1引数の配列の要素の方が大きかった回数が、第2引数の配列の要素の方が大きかった回数よりも多い場合

  • 1 … 第2引数の配列の要素の方が大きかった回数が、第1引数の配列の要素の方が大きかった回数よりも多い場合

  • 0 … 両方のカウントが等しい場合

たとえば冒頭の配列の場合、出力は次のようになります。

const output = 1;

これは、arr1の要素の方が大きかったのが4回、arr2の要素の方が大きかったのが5回であるためです。

コード例

const arr1 = [23, 67, 12, 87, 33, 56, 89, 34, 25];
const arr2 = [12, 60, 45, 54, 67, 84, 36, 73, 44];
const findDominance = (arr1 = [], arr2 = []) => {
    if(arr1.length !== arr2.length){
        return;
    };
    let count = 0;
    for(let i = 0; i < arr1.length; i++){
        const el1 = arr1[i];
        const el2 = arr2[i];
        const diff = el2 - el1;
        console.log(diff)
        count += diff / Math.abs(diff);
    };
    return count / Math.abs(count);
};
console.log(findDominance(arr1, arr2));

ロジックの解説

このコードのポイントは次の2点です。

  • diff = el2 - el1 で差分を計算します。arr2側の要素が大きければ正の値、arr1側の要素が大きければ負の値になります。

  • diff / Math.abs(diff) は、diffが正なら +1、負なら -1 になります。これにより、大小関係を符号だけで表現できます。

ループ内でこの値を合計した count は、「arr2が勝った回数からarr1が勝った回数を引いた値」を意味します。最後に count / Math.abs(count) を返すことで、結果を -1 または 1 に正規化しています。

注意点:Math.sign()を使った改善版

この処理は Math.sign() を使うとさらに簡潔に書けます。また、元のコードでは両者のカウントが完全に一致した場合(count === 0)や対応する要素が等しい場合(diff === 0)には、0除算によってNaNが発生する可能性があります。次のように書き換えると安全です。

const findDominance = (arr1 = [], arr2 = []) => {
    if(arr1.length !== arr2.length){
        return;
    };
    let count = 0;
    for(let i = 0; i < arr1.length; i++){
        count += Math.sign(arr2[i] - arr1[i]);
    };
    return Math.sign(count);
};

Math.sign() は引数が正なら 1、負なら -1、0 なら 0 を返すため、引き分けの場合も意図どおりに 0 を返せます。

出力

元のコードを実行すると、コンソールには次のように出力されます。

-11
-7
33
-33
34
28
-53
39
19
1

各行の数値は対応する要素同士の差分(arr2[i] - arr1[i])であり、最後の 1 が関数の戻り値です。arr2側が大きいペアが5つ、arr1側が大きいペアが4つあるため、結果として 1 が返されます。

  1. JavaScriptで2つの配列のサブセット(部分集合)を判定する方法

    リテラル値からなる2つの配列を受け取り、第2引数の配列が第1引数の配列の部分集合(サブセット)であるかどうかを判定するJavaScript関数を作成する必要があります。この判定を行う際には、以下の条件を考慮する必要があります。array2には、array1に含まれるすべての値が定義されている必要があるarray1に重複した値が存在する場合、その重複数もarray2側で考慮されなければならない具体例たとえば、arr1 = [a, a] と arr2 = [b, a] を比較すると、「a」は最初の配列に2回登場していますが、2番目の配列では1回しか登場していないため、isSubset の結果は f

  2. JavaScriptで2つの配列の対応する各要素にカスタム関数を適用する方法

    問題ここでは、次のようなJavaScript関数を作成する必要があります。第一引数:2つの引数を受け取り、値を返すコールバック関数第二引数・第三引数:ほぼ同じ長さの2つの配列この関数は、2つの入力配列から対応する要素同士をペアにしてコールバック関数へ渡し、その戻り値を要素とする新しい配列を構築して返すものとします。実装例以下のコードをご覧ください。const arr1 = [1, 2, 3, 4]; const arr2 = [5, 6, 7, 8]; const add = (a, b) => a + b; const applyFunction = (callback = () =&