Files
2022-01-20 20:30:18 +01:00

3.3 KiB

id, title, challengeType, forumTopicId, dashedName
id title challengeType forumTopicId dashedName
587d7b86367417b2b2512b3b インデックスの使用時のオフバイワンエラーを理解する 1 301189 catch-off-by-one-errors-when-using-indexing

--description--

オフバイワンエラー (OBOE と呼ばれることもあります) は、文字列または配列の特定のインデックスをターゲットにしようとしているとき (セグメントをスライスするまたはアクセスするため)、あるいはインデックスをループ処理するときに発生します。 JavaScript のインデックスは、1 からではなく、0 から始まります。つまり、最後のインデックスは常にアイテムの長さよりも 1 小さくなります。 最後のインデックスと等しい長さのインデックスにアクセスしようとすると、プログラムから「インデックスが範囲外」という参照エラーがスローされたり、undefined が出力されたりする場合があります。

引数としてインデックスの範囲を受け取る文字列メソッドや配列メソッドを使用する場合は、ドキュメントを確認して、それらがインクルーシブ (対象のインデックスのアイテムも返される一部となる) かどうかを把握しておくと役に立ちます。 オフバイワンエラーの例を次に示します。

let alphabet = "abcdefghijklmnopqrstuvwxyz";
let len = alphabet.length;
for (let i = 0; i <= len; i++) {
  console.log(alphabet[i]);
}
for (let j = 1; j < len; j++) {
  console.log(alphabet[j]);
}
for (let k = 0; k < len; k++) {
  console.log(alphabet[k]);
}

最初の例ではループが 1 回多く繰り返され、2 つ目の例ではループが 1 回少なく繰り返されます (最初のインデックスである 0 が欠落しています)。 3つ 目は正しい例です。

--instructions--

次の関数で 2 つのインデックスエラーを修正して、1 から 5 までのすべての数字がコンソールに出力されるようにしてください。

--hints--

ループが最初のインデックスから開始するように、ループの初期条件を設定します。

assert(code.match(/i\s*?=\s*?0\s*?;/g).length == 1);

インデックスが 0 から始まるように、ループの初期条件を修正します。

assert(!code.match(/i\s?=\s*?1\s*?;/g));

ループが最後のインデックスで止まるように、ループの終了条件を設定します。

assert(code.match(/i\s*?<\s*?len\s*?;/g).length == 1);

ループが length の 1 つ前で止まるように、ループの終了条件を修正します。

assert(!code.match(/i\s*?<=\s*?len;/g));

--seed--

--seed-contents--

function countToFive() {
  let firstFive = "12345";
  let len = firstFive.length;
  // Only change code below this line
  for (let i = 1; i <= len; i++) {
  // Only change code above this line
    console.log(firstFive[i]);
  }
}

countToFive();

--solutions--

function countToFive() {
 let firstFive = "12345";
 let len = firstFive.length;
 // Only change code below this line
 for (let i = 0; i < len; i++) {
 // Only change code above this line
   console.log(firstFive[i]);
 }
}

countToFive();