【JavaScript初心者向け】配列を使ったコード改善術 – paizaで学んだ10個の変数を1行にする方法

Paiza

こんにちは、いーさんです。

今回は、paizaラーニングの「数値の出現率」という問題を解いたときに学んだ、配列を使った効率的なコード管理について書いていきます。

最初に書いたコードは動くには動いたのですが、かなり冗長で読みにくいコードになってしまいました。それを改善する過程で、配列の使い方について大きな気づきがあったので共有します。

取り組んだ問題

paizaの「数値の出現率」という問題です。

問題概要:
0〜9の数値がN個与えられるので、各数値(0〜9)が何回出現したかをカウントする、というものです。

例えば、[1, 2, 1, 3, 2, 1, 0] という入力なら、0が1回、1が3回、2が2回、3が1回…といった形で出力します。

最初に書いたコード

まず、私が最初に書いたコードがこちらです。

process.stdin.resume();
process.stdin.setEncoding('utf8');
var lines = [];
var reader = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout
});
reader.on('line', (line) => {
  lines.push(line);
});
reader.on('close', () => {
  const N = Number(lines[0]);
  const A = lines[1].split(" ").map(Number);
  
  let count0 = 0;
  let count1 = 0;
  let count2 = 0;
  let count3 = 0;
  let count4 = 0;
  let count5 = 0;
  let count6 = 0;
  let count7 = 0;
  let count8 = 0;
  let count9 = 0;
  
  for(let x of A){
      if(x === 0){
          count0++;
      } else if(x === 1){
          count1++;
      } else if(x === 2){
          count2++;
      } else if(x === 3){
          count3++;
      } else if(x === 4){
          count4++;
      } else if(x === 5){
          count5++;
      } else if(x === 6){
          count6++;
      } else if(x === 7){
          count7++;
      } else if(x === 8){
          count8++;
      } else {
          count9++;
      }
  }
  
  console.log(count0, count1, count2, count3, count4, count5, count6, count7, count8, count9);
});

一応正解にはなりました。 でも、このコードには明らかに問題がありました。

コードの問題点

自分で書いていて「これはまずいな…」と感じたポイントは以下の通りです:

1. 変数が多すぎる

count0からcount9まで、10個も変数を宣言しています。たった10個の数値をカウントするだけなのに、10個も変数が必要というのは明らかに冗長です。

2. if-else文が長すぎる

9個も連なったelse if。スクロールしないと全体が見えません。これでは可読性が非常に悪いです。

3. 拡張性がない

もし「0〜99までの100個の数値をカウントしてください」という問題であったら、100個の変数と99個のelse ifを書く必要が生じ記述がほぼ不可能。

4. 似たような変数名で混乱しやすい

count0count1count2…。変数名が似すぎていて、コピペミスも起こしやすいです。

改善後のコード

改善版のコード

process.stdin.resume();
process.stdin.setEncoding('utf8');
var lines = [];
var reader = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout
});
reader.on('line', (line) => {
  lines.push(line);
});
reader.on('close', () => {
  const N = Number(lines[0]);
  const A = lines[1].split(" ").map(Number);
  
  const count = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
  
  for(let x of A){
      count[x]++;
  }
  
  console.log(count.join(" "));
});

圧倒的にシンプルになりました!

どこが改善されたのか

1. 配列で管理

// Before
let count0 = 0;
let count1 = 0;
...

// After
const count = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

10個の変数を1つの配列にまとめました。これだけで宣言部分が圧倒的にスッキリします。

2. インデックスを活用

// Before
if(x === 0){
    count0++;
} else if(x === 1){
    count1++;
}
...

// After
count[x]++;

これが一番の改善ポイントです。

数値xがそのまま配列のインデックスになっているので、count[x]++だけで該当する数値のカウントを増やせます。

if文が9個も必要だったのが、たった1行になりました。

3. join()で出力

// Before
console.log(count0, count1, count2, count3, count4, count5, count6, count7, count8, count9);

// After
console.log(count.join(" "));

join(" ")を使えば、配列の要素をスペース区切りで出力できます。変数を10個も並べる必要がなくなりました。

学んだこと

この改善を通じて、いくつか重要なことを学びました。

1. 繰り返しパターンは配列化を検討

似たような変数や処理が繰り返し出てきたら、それは配列で管理できないか考えるべきサインです。

繰り返しパターンの例:

  • count0, count1, count2… → count[0], count[1], count[2]
  • if(x === 0), if(x === 1)… → count[x]

2. インデックスとデータの対応関係を意識する

今回のケースでは、「数値0のカウント」を配列の0番目、「数値1のカウント」を配列の1番目…というように、データの値とインデックスが一致していました。

この対応関係に気づけば、配列を使った管理が自然に思いつくようになります。

3. コードの可読性は重要

動けばいいというものではありません。

  • 自分が後で見返したときに理解しやすいか
  • 他の人が見ても何をしているか分かるか
  • バグを見つけやすいか

これらを意識すると、自然と簡潔なコードを書こうとするようになります。

4. 拡張性を考える

もし問題が「0〜9」から「0〜99」に変わったら?

改善前のコード: 100個の変数と99個のelse ifを書き直す必要がある
改善後のコード: 配列の初期化をArray(100).fill(0)に変えるだけ

拡張性の違いは明らかです。

まとめ

今回の学びをまとめると:

繰り返しパターンを見つけたら配列化を検討
インデックスとデータの対応関係を活用
可読性と拡張性を意識したコーディング

最初のコードは冗長で恥ずかしいですが、こうして改善できたことが大きな学びになりました。

プログラミング学習では、「動くコード」を「良いコード」に改善していくプロセスがとても重要だと実感しています。

同じようにpaizaで学習している方の参考になれば嬉しいです!


今回学んだパターン:

  • 似た変数が増えたら配列で管理
  • count[value]++でカウント
  • array.join(" ")で出力

次回もpaizaで学んだことをアウトプットしていきます。

関連記事:

  • (次の記事へのリンク)

この記事は paizaラーニング の学習記録です。

コメント

タイトルとURLをコピーしました