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

JavaScriptで配列内の重複しない要素だけの合計を求める方法

次のような数値の配列があるとします。

const arr = [14, 54, 23, 14, 24, 33, 44, 54, 77, 87, 77, 14];

この配列の中から一度しか出現しない要素(重複していない要素)だけを取り出し、その合計を計算するJavaScript関数を作成してみましょう。

期待される出力

上記の配列の場合、一度しか出現しない要素は「23、24、33、44、87」の5つです。したがって、出力は以下のようになります。

23 + 24 + 33 + 44 + 87 = 211

実装の考え方

ある要素が配列内で一意かどうかを判定するには、indexOf()lastIndexOf()の戻り値を比較する方法が有効です。両者が同じインデックスを返す場合、その値は配列内に一度しか存在しないことを意味します。逆に、異なるインデックスを返す場合は重複しているため、合計から除外します。

サンプルコード

const arr = [14, 54, 23, 14, 24, 33, 44, 54, 77, 87, 77, 14];

const nonRepeatingSum = arr => {
  let res = 0;
  for(let i = 0; i < arr.length; i++){
    // 先頭位置と末尾位置が異なる場合は重複要素なのでスキップ
    if(arr.indexOf(arr[i]) !== arr.lastIndexOf(arr[i])){
      continue;
    };
    res += arr[i];
  };
  return res;
};

console.log(nonRepeatingSum(arr));

実行結果

211

別のアプローチ:filter()とreduce()を活用する

より関数型らしい書き方として、filter()で一意な要素だけを抽出し、reduce()で合計を算出する方法もあります。コードが簡潔になり、意図も読み取りやすくなります。

const arr = [14, 54, 23, 14, 24, 33, 44, 54, 77, 87, 77, 14];

const nonRepeatingSum = arr =>
  arr
    .filter((val, i) => arr.indexOf(val) === arr.lastIndexOf(val))
    .reduce((sum, val) => sum + val, 0);

console.log(nonRepeatingSum(arr)); // 211

まとめ

  • indexOf()lastIndexOf()の結果を比較することで、要素が配列内で一意かどうかを簡単に判定できます。
  • forループを使う方法でも、filter()+reduce()を使う方法でも、どちらも結果は同じ「211」となります。
  • データ量が多い配列を扱う場合は、あらかじめ各要素の出現回数をMapやオブジェクトに記録しておくと、計算量をO(n)に抑えられます。
  1. JavaScriptで配列の交互要素(1つおきの要素)の合計を求める方法

    交互要素の合計とは本記事では、数値の配列を唯一の引数として受け取り、配列内の交互の要素(インデックスが偶数の位置にある要素)の合計を計算して返すJavaScript関数の実装方法を解説します。例えばー入力配列が以下の場合を考えてみましょう。const arr = [1, 2, 3, 4, 5, 6, 7];この場合、出力は次のようになります。1 + 3 + 5 + 7 = 16サンプルコード以下が実際の実装コードです。const arr = [1, 2, 3, 4, 5, 6, 7]; const alternativeSum = (arr = []) => {    

  2. JavaScriptのreduce()メソッドで配列要素の積を求める方法

    問題JavaScriptで、配列 arr を引数として受け取る関数を作成します。この関数は、配列内のすべての要素を掛け合わせた積を計算し、その結果を返す必要があります。解決策:reduce()メソッドを使う配列の全要素を集約して単一の値を得たい場合、Array.prototype.reduce() メソッドが最適です。reduce() は配列の各要素に対してコールバック関数を順に実行し、結果をアキュムレータ(累積値)に蓄えていきます。積を求める場合は、初期値として「1」を指定するのがポイントです。1は乗法における単位元のため、計算結果に影響を与えず、さらに空の配列が渡された場合でも正しく 1