JavaScriptでネストされた配列の加重和を計算する方法
問題
任意の深さまでネストされた配列 arr を唯一の引数として受け取り、その加重和(weighted sum)を計算して返す JavaScript 関数を作成する必要があります。
加重和とは、各要素に「その要素が属するネストの深さ(レベル)」を掛けた値を、配列全体にわたって合計したものです。
入力例と出力例
たとえば、関数に次の配列を渡した場合を考えてみましょう。
const arr = [4, 7, [6, 1, [5, 2]]];
このとき、期待される出力は次のとおりです。
const output = 46;
なぜ 46 になるのか?
最上位の要素はレベル1、その中に入っている要素はレベル2、さらにその内側はレベル3 として扱います。各要素に対応するレベルを掛けて合計すると、次のように計算されます。
(4 * 1) + (7 * 1) + (6 * 2) + (1 * 2) + (5 * 3) + (2 * 3) = 46
実装コード
この問題は再帰呼び出しを使うことで、シンプルかつ読みやすく解決できます。
const arr = [4, 7, [6, 1, [5, 2]]];
const findWeightedSum = (arr = [], level = 1, res = 0) => {
for (let i = 0; i < arr.length; i++) {
if (typeof arr[i] === 'number') {
// 数値なら現在のレベルを掛けて加算
res += (level * arr[i]);
} else if (Array.isArray(arr[i])) {
// 配列ならレベルを1つ深くして再帰的に処理
res = findWeightedSum(arr[i], level + 1, res);
}
}
return res;
};
console.log(findWeightedSum(arr));
実行結果
46
コードのポイント
- デフォルトパラメータ
level = 1とres = 0を使うことで、最初の呼び出し時に特別な初期化を行わずに済みます。 - 要素が数値(
typeof arr[i] === 'number')であれば、そのレベルを掛けて累積変数resに加算します。 - 要素が配列(
Array.isArray(arr[i]))であれば、レベルを +1 して自分自身を再帰的に呼び出します。 - 重要なのは、
return findWeightedSum(...)ではなくres = findWeightedSum(...)としている点です。returnしてしまうとループがそこで終了し、同じ階層に残った後続の要素が処理されなくなります。結果をresに代入することで、すべての要素を正しく走査できます。
-
【JavaScript】配列内のネストされたオブジェクトの値を合計する方法
この記事では、JavaScriptを使って、配列内にネストされた(入れ子構造の)オブジェクトの値を合計する方法を解説します。サンプルコードでは、JSONデータの複数階層に格納された数値(costNum)を順番に取り出し、その合計をブラウザ上に表示します。 コード例 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=d
-
JavaScriptで配列の部分和(累積和)を求める方法
本記事では、数値の配列(ネストされた配列)を受け取り、各サブ配列ごとに「部分和」の配列を作成するJavaScript関数の実装方法を解説します。部分和(累積和)とは、配列内の各要素が「その要素自身と、それ以前のすべての要素の合計」になるように計算した配列のことです。処理内容の例たとえば、入力配列が以下の場合を考えてみましょう。const arr = [ [1, 1, 1, -1], [1, -1, -1], [1, 1] ];この場合、期待される出力は次のようになります。const output = [ [1, 2, 3, 2], [1, 0, -1], [1, 2]