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

JavaScriptで配列から連続して繰り返されない最初の要素のインデックスを見つける方法

問題の概要

数値や文字列のリテラルが格納された配列があり、そのほとんどの要素は隣り合う形で繰り返し出現しています。今回の課題は、この配列を引数として受け取り、「連続して繰り返されていない」最初の要素のインデックスを返す関数を実装することです。

もし該当する要素が配列内にひとつも存在しない場合は、-1 を返す仕様とします。それでは、実際のコードを見ていきましょう。

実装の考え方

アプローチはシンプルです。for ループで配列を先頭から順に走査し、現在の要素と隣接する次の要素を比較します。

  • 両者が異なる場合:これまでに連続する繰り返しが検出されていなければ(カウントが0なら)、その時点のインデックスを答えとして返します。
  • 両者が同じ場合:カウントを増やして、連続出現中であることを記録します。

ループが最後まで完了しても該当する要素が見つからなければ、-1 を返します。

コード例

const arr = ['d', 'd', 'e', 'e', 'e', 'k', 'j', 'j', 'h'];
const firstNonRepeating = arr => {
    let count = 0;
    for(let ind = 0; ind < arr.length-1; ind++){
        if(arr[ind] !== arr[ind+1]){
            if(!count){
                return ind;
            };
            count = 0;
        } else {
            count++;
        }
    };
    return -1;
};
console.log(firstNonRepeating(arr));

実行結果

コンソールには次のように出力されます。

5

動作の解説

この例では、'd' は2回、'e' は3回連続して出現していますが、インデックス5にある 'k' は1回しか登場していません。したがって、連続して繰り返されていない最初の要素は 'k' であり、関数は 5 を返します。

注意点:末尾の要素の扱い

この実装では、ループ条件が ind < arr.length - 1 となっているため、配列の最後の要素は直接評価されません。たとえば ['a', 'a', 'b'] のような配列では、唯一無二の要素である 'b'(インデックス2)が存在しても、この関数は -1 を返してしまいます。

すべての要素を確実に判定対象にしたい場合は、ループ終了後に「最後の要素が直前の要素と異なるか」を追加でチェックする処理を加えるとよいでしょう。

  1. JavaScript RegExp の \s メタ文字とは?空白文字の検索方法を解説

    JavaScriptの正規表現における \s メタ文字は、空白文字(whitespace)を検索するために使用されます。文字列の中に空白が含まれているかどうかを簡単に判定したい場合に便利です。\s がマッチする空白文字の種類\s にマッチする空白文字は以下のとおりです。スペース(半角空白)タブ文字(\t)キャリッジリターン(\r)改行文字(\n)垂直タブ文字(\v)フォームフィード文字(\f)使用例次のコードでは、test() メソッドを使って、各文字列に空白文字が含まれているかどうかを判定しています。// 空白を含まない文字列の場合: console.log(/\s/.test(1)); c

  2. JavaScriptのファーストクラス関数とは?特徴と使い方を実例で解説

    ファーストクラス関数(第一級関数)とは? JavaScriptでは、関数もオブジェクトの一種として扱われます。そのため、関数を別の関数の引数(パラメータ)として渡したり、関数の中で別の関数を戻り値として返したりすることが可能です。 このような性質を持つことから、JavaScriptの関数はファーストクラス関数(第一級関数)と呼ばれています。つまり、関数は変数・オブジェクト・配列などに自由に格納できる「値」だということです。 さらに、関数を引数として受け取る、関数を戻り値として返す、あるいはその両方を行う関数は高階関数(Higher Order Function)と呼ばれます。 ファーストクラ