JSで存在するかを調べる際に使う indexOf をもっとスマートに書く

著者
Kato83
作成日
2020/04/04 - 19:29
更新日
2023/03/02 - 14:00

JavaScriptにおいて、調べたい要素が特定の要素に含まれているかを調べる方法として indexOf がよく使われるが、 indexOf の戻り値の性質上以下のような条件分岐が使われている記事をよくみかけますよね?

const array = ["a", "b", "c", "d"];

// 要素が含まれているか調べる
// array.indexOf("c") は 2 が返され、-1以上なので true になる
if (array.indexOf("c") > -1) {
  // 存在する場合
} else {
  // 存在しない場合
}

indexOf は要素が存在しなかったときは -1 を返す性質上、条件分岐でそのまま使用してしまうと true になってしまいます。

更に、要素が0番目にあった場合は 0 を返すため、条件分岐でそのまま調べると false になってしまいます。

そのため、上記のような条件分岐にする必要があるのですが、もっとスマートな記述方法があるので紹介します。

~(チルダ)演算子を利用する

NOT 演算は、各ビットで実行します。NOT a は、a を反転した値 (1 の補数として知られています) を出力します。

引用元 : ビット演算子 - JavaScript | MDN

あまり聞き慣れないワードかと思います、工業や商業系の知識をかじっている人であればもしかしたらピンとくるかもしれないですが。

本当に~(チルダ)演算子で正しく動作するのか、簡単なテストコードを以下に記載します。

const array = ["a", "b", "c", "d"];

/** 動作テスト用関数 */
function existResult(flg) {
  if (flg) {
    console.log("存在する");
  } else {
    console.log("存在しない");
  }
}

existResult(~array.indexOf("a"));
// → 存在する

existResult(~array.indexOf("b"));
// → 存在する

existResult(~array.indexOf("c"));
// → 存在する

existResult(~array.indexOf("d"))
// → 存在する

existResult(~array.indexOf("e"))
// → 存在しない

Array.includes を使う

IE11を動作対象に含めない or webpack (babel) を使用する場合は Array.includes を利用する方が先頭に~(チルダ)演算子を置かずに済むので、こちらの方がスマートと言えるでしょう。

includes() メソッドは、特定の要素が配列に含まれているかどうかを true または false で返します。

引用元 : Array.prototype.includes() - JavaScript | MDN

const array = ["a", "b", "c", "d"];

/** 動作テスト用関数 */
function existResult(flg) {
  if (flg) {
    console.log("存在する");
  } else {
    console.log("存在しない");
  }
}

existResult(array.includes("a"));
// → 存在する

existResult(array.includes("b"));
// → 存在する

existResult(array.includes("c"));
// → 存在する

existResult(array.includes("d"))
// → 存在する

existResult(array.includes("e"))
// → 存在しない

ぜひ試してみてください。

Category