- JavaScript
JavaScript includesとindexOfの違い|配列の存在チェック
includes と indexOf の違いは、includes が「含まれるかどうか」を true / false で返し、indexOf が「何番目にあるか」を数値(無ければ -1)で返す点です。 存在チェックだけなら includes、位置が必要なら indexOf を選びます。もう1つの違いは NaN の扱いで、includes は NaN を見つけられますが、indexOf は見つけられません。
この記事では、配列の存在チェックに使える9つの方法を1つの表にまとめ、NaN・-0・空き要素・型違いでの結果の差を Node.js v22.22.2 で実行して確かめました。 オブジェクト配列の検索(id 検索・複数条件・部分一致・ネストしたプロパティ・重複チェック)のコピペ例、1万件と100万件での includes と Set.has の実測値、「いずれかを含む」「すべてを含む」の判定パターンまで扱います。実行結果は、比べやすいように「式」と「値」を1行ずつ並べた形で載せています。
配列の存在チェックの早見表
| メソッド | 戻り値 | 見つからないとき | 比較方法 | NaN を見つけられるか | オブジェクト配列で使えるか |
|---|---|---|---|---|---|
arr.includes(v) |
true / false | false | SameValueZero | 見つけられる | 同じ参照のときだけ |
arr.indexOf(v) |
最初の位置 | -1 | 厳密等価(===) | 見つけられない | 同じ参照のときだけ |
arr.lastIndexOf(v) |
最後の位置 | -1 | 厳密等価(===) | 見つけられない | 同じ参照のときだけ |
arr.some(fn) |
true / false | false | 関数で自由に決める | Number.isNaN を渡せば可 |
使える(条件を書ける) |
arr.find(fn) |
最初の要素 | undefined | 関数で自由に決める | Number.isNaN を渡せば可 |
使える(要素そのものが返る) |
arr.findIndex(fn) |
最初の位置 | -1 | 関数で自由に決める | Number.isNaN を渡せば可 |
使える |
arr.findLast(fn) |
最後の要素 | undefined | 関数で自由に決める | Number.isNaN を渡せば可 |
使える |
arr.filter(fn) |
条件に合う全要素の配列 | 空の配列 | 関数で自由に決める | Number.isNaN を渡せば可 |
使える(複数件ほしいとき) |
set.has(v) |
true / false | false | SameValueZero | 見つけられる | 同じ参照のときだけ |
SameValueZero は、=== とほぼ同じで、NaN どうしを等しいとみなす点だけが違う比較方法です。
基本の動きを [10, 20, 30, 20] で確かめた結果です。
const a = [10, 20, 30, 20];
a.includes(20) true
a.indexOf(20) 1
a.lastIndexOf(20) 3
a.some(x => x === 20) true
a.find(x => x > 15) 20
a.findIndex(x => x > 15) 1
a.findLast(x => x > 15) 20
a.findLastIndex(x => x > 15) 3
a.filter(x => x === 20) [20,20]
new Set(a).has(20) true
見つからない値(99)で試した結果です。
a.includes(99) false
a.indexOf(99) -1
a.lastIndexOf(99) -1
a.some(x => x === 99) false
a.find(x => x === 99) undefined
a.findIndex(x => x === 99) -1
a.findLast(x => x === 99) undefined
a.filter(x => x === 99) []
new Set(a).has(99) false
includesとindexOfの違いを実行結果で確かめる
戻り値の違いとif文での書き方
includes は真偽値を返すので、そのまま if に書けます。indexOf は位置を返すので、-1 と比べる必要があります。
const a = [10, 20, 30, 20];
// includes:そのまま条件に書ける
if (a.includes(10)) { /* 含まれる */ }
// indexOf:-1 と比べる
if (a.indexOf(10) !== -1) { /* 含まれる */ }
indexOf の結果をそのまま if に入れると、先頭(0番目)で見つかったときに「含まれない」側へ進みます。 0 は条件式で false として扱われるためです。
console.log(a.indexOf(10) ? 'truthy' : 'falsy(0)');
falsy(0)
| 直す前 | 直した後 | 理由 |
|---|---|---|
if (a.indexOf(10)) |
if (a.includes(10)) |
0 番目で見つかると false 扱いになる |
if (a.indexOf(99) >= 0) |
if (a.includes(99)) |
意図がそのまま読める |
const i = a.indexOf(v); if (i !== -1) a.splice(i, 1); |
そのまま | 位置を使うので indexOf が合っている |
「あるかどうか」だけなら includes、「どこにあるか」を使うなら indexOf と決めておくと、読み手にも意図が伝わります。
第2引数で検索の開始位置を決める
includes と indexOf は、第2引数で検索を始める位置を指定できます。負の数は末尾からの位置です。
a.includes(10, 1) false (1番目以降に 10 は無い)
a.includes(20, -1) true (最後の1件だけを見る)
a.indexOf(20, 2) 3 (2番目以降で最初の 20)
indexOf と第2引数を組み合わせると、同じ値のすべての位置を順に取り出せます。
const positions = [];
let i = a.indexOf(20);
while (i !== -1) {
positions.push(i);
i = a.indexOf(20, i + 1);
}
// positions は [1, 3](上の indexOf(20) と indexOf(20, 2) の結果から)
NaN・-0・空き要素・型違いでの結果の差
includes と indexOf が違う答えを返す入力を、4種類まとめて確かめます。
NaN:includesは見つけ、indexOfは見つけない
const n = [1, NaN, 3];
n.includes(NaN) true
n.indexOf(NaN) -1
n.lastIndexOf(NaN) -1
n.some(x => x === NaN) false
n.some(Number.isNaN) true
n.findIndex(Number.isNaN) 1
n.find(Number.isNaN) NaN
new Set(n).has(NaN) true
n.filter(Number.isNaN).length 1
NaN は、=== で比べると自分自身とも等しくならない特別な値です。indexOf は === で比べるので見つけられず、includes と Set.has は NaN どうしを等しいとみなす比較(SameValueZero)なので見つけられます。 some や findIndex に x => x === NaN と書いても見つかりません。関数を使うときは Number.isNaN を渡します。NaN の位置を知りたいときは findIndex(Number.isNaN) が使えます。
数値に変換できなかった入力(Number('abc') など)が配列に混ざる処理では、この差が結果に表れます。
-0:どのメソッドも0と同じとみなす
[0].includes(-0) true
[0].indexOf(-0) 0
[-0].includes(0) true
new Set([0]).has(-0) true
[0].some(x => Object.is(x, -0)) false
[-0].some(x => Object.is(x, -0)) true
0 と -0 は、includes・indexOf・Set.has のどれでも同じ値として扱われます。-0 だけを区別して探したい場合に限り、Object.is を使った関数を some に渡します。
空き要素:includesはundefinedとして見つける
[1, , 3] のように、値が入っていない位置(空き要素)がある配列での結果です。
const h = [1, , 3];
h.includes(undefined) true
h.indexOf(undefined) -1
h.some(x => x === undefined) false
h.findIndex(x => x === undefined) 1
1 in h false
new Set(h).has(undefined) true
h.filter(x => x === undefined).length 0
[1, undefined, 3].indexOf(undefined) 1
includes・findIndex は空き要素を undefined として扱い、indexOf・some・filter は空き要素を飛ばします。 明示的に undefined を入れた配列なら、indexOf も 1 を返します。空き要素は new Array(3) や、配列リテラルの書き間違い(カンマの連続)、delete arr[1] で生まれます。配列を作るときに Array.from({ length: 3 }) や fill を使うと、空き要素のない配列になり、メソッドによる差を気にせずに済みます。
| メソッド | 空き要素の扱い(実行結果から) |
|---|---|
| includes / findIndex / Set への変換 | undefined として扱う |
| indexOf / some / filter | 飛ばす |
型違い:"1"と1は別の値
const t = [1, 2, 3];
t.includes('1') false
t.indexOf('1') -1
t.some(x => x == '1') true
t.includes(Number('1')) true
t.map(String).includes('1') true
new Set(t).has('1') false
[null].includes(undefined) false
['a'].includes('A') false
includes・indexOf・Set.has は型を変換せずに比べるので、文字列の "1" と数値の 1 は一致しません。 フォームの入力値や URL のパラメーターは文字列で届くため、数値の配列と比べるときは Number(value) で型をそろえてから調べます。大文字と小文字も区別されるので、区別したくないときは両方を toLowerCase() でそろえます。
// 直す前:入力は文字列なので一致しない
const selectedId = '2';
[1, 2, 3].includes(selectedId); // false
// 直した後:型をそろえる
[1, 2, 3].includes(Number(selectedId)); // true
4種類の差のまとめ
| 入力 | includes | indexOf | Set.has | some(=== で比較) |
|---|---|---|---|---|
[1, NaN, 3] から NaN |
true | -1 | true | false |
[0] から -0 |
true | 0 | true | true |
[1, , 3] から undefined |
true | -1 | true | false |
[1, 2, 3] から "1" |
false | -1 | false | false |
配列ではない値に使ったときのエラー文
undefined.includes(1) TypeError: Cannot read properties of undefined (reading 'includes')
({}).includes(1) TypeError: {}.includes is not a function
'abc'.includes(/b/) TypeError: First argument to String.prototype.includes must not be a regular expression
'abc'.includes('b') true
1行目は、配列が入っているはずの変数が undefined だったときのエラーです。API の応答など、値が無い可能性があるときは (list ?? []).includes(v) と書くか、list?.includes(v) で undefined を受け取る形にします。2行目のとおり、普通のオブジェクトには includes がありません。キーの有無は Object.hasOwn(obj, key) や key in obj で調べます。文字列にも同名の includes があり、こちらは部分文字列を探します。正規表現で探したいときは test を使います。
オブジェクト配列を検索するコピペ集
以降の例は、次のデータを使います。
const users = [
{ id: 1, name: 'Sato Taro', role: 'admin', active: true, address: { city: 'Tokyo' }, tags: ['js', 'go'] },
{ id: 2, name: 'Suzuki Hana', role: 'member', active: false, address: { city: 'Osaka' }, tags: ['php'] },
{ id: 3, name: 'Tanaka Ken', role: 'member', active: true, address: null, tags: [] },
{ id: 4, name: 'Sato Yuki', role: 'member', active: true, address: { city: 'Tokyo' }, tags: ['js'] },
];
includesとindexOfは「同じ参照」しか見つけない
users.includes({ id: 1 }) false
users.includes(users[0]) true
users.indexOf({ id: 1 }) -1
{ id: 1 } と書くたびに新しいオブジェクトが作られるので、中身が同じでも別のものとして扱われます。オブジェクト配列では、条件を関数で書ける some・find・findIndex・filter を使います。
idで検索する
users.some(u => u.id === 2); // 存在するか
users.find(u => u.id === 2)?.name; // 要素を取り出す
users.find(u => u.id === 9); // 無いとき
users.findIndex(u => u.id === 3); // 位置
users.some(u => u.id === 2) true
users.find(u => u.id === 2)?.name Suzuki Hana
users.find(u => u.id === 9) undefined
users.findIndex(u => u.id === 3) 2
find は見つからないと undefined を返すので、プロパティを続けて読むときは ?. を付けておくと TypeError になりません。
| ほしいもの | メソッド |
|---|---|
| あるかどうか(true / false) | some |
| 最初の1件 | find |
| 最後の1件 | findLast |
| 位置(更新や削除に使う) | findIndex |
| 条件に合う全件 | filter |
複数条件で検索する
users.filter(u => u.role === 'member' && u.active).map(u => u.id);
users.some(u => u.role === 'admin' && u.active);
[3,4]
true
条件をオブジェクトで受け取りたいとき(検索フォームの入力など)は、次の形にまとめられます。
const cond = { role: 'member', active: true };
users.filter(u => Object.entries(cond).every(([k, v]) => u[k] === v)).map(u => u.id);
[3,4]
部分一致で検索する
users.filter(u => u.name.toLowerCase().includes('sato')).map(u => u.name);
["Sato Taro","Sato Yuki"]
ここで使っている includes は文字列の includesです。配列の includes は要素の完全一致、文字列の includes は部分一致、と役割が分かれています。大文字と小文字を区別しないように、両方を小文字にそろえています。
ネストしたプロパティで検索する
users.filter(u => u.address?.city === 'Tokyo').map(u => u.id);
[1,4]
id が 3 のデータは address が null です。?. を付けずに書くと、その要素で止まります。
users.filter(u => u.address.city === 'Tokyo')
TypeError: Cannot read properties of null (reading 'city')
ネストしたプロパティをたどるときは ?.(オプショナルチェーン)を付けると、途中が null や undefined の要素は「条件に合わない」として扱われます。
要素の中の配列を調べるときは、内側で配列の includes を使います。
users.filter(u => u.tags.includes('js')).map(u => u.id);
users.findLast(u => u.active)?.id;
[1,4]
4
重複をチェックする
const items = [{ id: 1 }, { id: 2 }, { id: 1 }, { id: 3 }, { id: 2 }];
// 重複があるか
new Set(items.map(i => i.id)).size !== items.length;
// 重複している id の一覧
[...new Set(items.map(i => i.id).filter((id, i, arr) => arr.indexOf(id) !== i))];
// id で重複を取り除く(あとに出てきた要素が残る)
[...new Map(items.map(i => [i.id, i])).values()];
// 最初に重複した要素
const seen = new Set();
items.find(i => seen.has(i.id) || !seen.add(i.id));
// id ごとの件数
Object.fromEntries(Object.entries(Object.groupBy(items, i => i.id)).map(([k, v]) => [k, v.length]));
true
[1,2]
[{"id":1},{"id":2},{"id":3}]
{"id":1}
{"1":2,"2":2,"3":1}
2つ目の arr.indexOf(id) !== i は、「最初に出てくる位置が、いまの位置と違う」=2回目以降の出現、という意味です。indexOf が位置を返すことを活かした書き方です。Object.groupBy は Node.js v22.22.2 で使えることを確認しました。
idで何度も探すならSetやMapにしておく
同じ配列を id で繰り返し探す処理では、先に Set や Map を作っておくと、1回ごとの検索が速くなります。
const ids = new Set(users.map(u => u.id));
ids.has(3);
const byId = new Map(users.map(u => [u.id, u]));
byId.get(4)?.name;
true
Sato Yuki
中身が同じオブジェクトかどうかで探す
[{ a: 1 }].some(o => JSON.stringify(o) === JSON.stringify({ a: 1 }));
true
JSON.stringify での比較は、プロパティの順番が違うと一致しない点と、undefined や関数が出力されない点に気を付けます。比べたいプロパティが決まっているなら、o => o.a === 1 のように条件を直接書くほうが確実です。
「いずれかを含む」「すべてを含む」を判定する
複数の値について調べるときは、some・every と includes を組み合わせます。
const have = ['js', 'go', 'sql'];
['php', 'go'].some(x => have.includes(x)) true (いずれかを含む)
['js', 'go'].every(x => have.includes(x)) true (すべてを含む)
['js', 'php'].every(x => have.includes(x)) false
!['php', 'rb'].some(x => have.includes(x)) true (どれも含まない)
['js', 'php', 'rb'].filter(x => !have.includes(x)) ["php","rb"] (足りないもの)
['js', 'php', 'go'].filter(x => have.includes(x)) ["js","go"] (共通するもの)
| 判定したいこと | 書き方 |
|---|---|
| いずれかを含む | wanted.some(x => have.includes(x)) |
| すべてを含む | wanted.every(x => have.includes(x)) |
| どれも含まない | !wanted.some(x => have.includes(x)) |
| 足りないものの一覧 | wanted.filter(x => !have.includes(x)) |
| 共通するものの一覧 | wanted.filter(x => have.includes(x)) |
空の配列に対する結果も確かめておきます。
[].every(x => false) true
[].some(x => true) false
every は空の配列に対して常に true を返します。 「選択された項目がすべて条件を満たすか」を調べる処理で、何も選択されていない場合を別扱いにしたいときは、wanted.length > 0 && wanted.every(...) と書きます。
Setの集合メソッドで書く
Node.js v22.22.2 では、Set に集合を比べるメソッドがあることを確認しました(typeof new Set().isSubsetOf が "function")。
const S = new Set(['js', 'go', 'sql']);
new Set(['js', 'go']).isSubsetOf(S); // すべてを含む
new Set(['php']).isDisjointFrom(S); // どれも含まない
[...S.intersection(new Set(['go', 'php']))]; // 共通するもの
S.isSupersetOf(new Set(['js']));
true
true
["go"]
true
ブラウザーでの対応状況は今回未確認(未実行)です。幅広い環境で動かす場合は、上の some・every と includes の組み合わせを使うと安心です。
||の連続をincludesで書き換える
1つの値が、いくつかの候補のどれかに当てはまるかを調べるときも、includes が使えます。
// 直す前
if (role === 'admin' || role === 'owner') { /* ... */ }
// 直した後
if (['admin', 'owner'].includes(role)) { /* ... */ }
['admin', 'owner'].includes('owner') が true になることを実行で確認しました。候補が増えても配列に足すだけで済みます。
includesとSet.hasの速度を1万件・100万件で実測する
includes は配列を先頭から順に見ていくので、件数が多いほど時間がかかります。Set.has は、ハッシュを使って値の場所を直接引くため、件数が増えても時間がほとんど変わりません。実際に測りました。
測定条件は次のとおりです。
- Node.js v22.22.2、0 から N-1 までの整数の配列
- 1000個の値を検索(半分は配列にある値、半分は無い値)
- 各7回測った中央値
const arr = Array.from({ length: N }, (_, i) => i);
const set = new Set(arr);
const qs = Array.from({ length: 1000 }, (_, i) => Math.floor(i * N / 1000) + (i % 2 ? 0 : N));
for (const q of qs) if (arr.includes(q)) c++; // includes
for (const q of qs) if (set.has(q)) c++; // Set.has
| 件数 N | includes × 1000回 | indexOf × 1000回 | some × 1000回 | Set.has × 1000回 | Set の作成(1回) |
|---|---|---|---|---|---|
| 1万件 | 7.87 ms | 6.36 ms | 33.00 ms | 0.0538 ms | 2.84 ms |
| 100万件 | 1231.61 ms | 1208.96 ms | 619.12 ms | 0.0656 ms | 127.11 ms |
100万件の配列で1000回検索すると、includes は約1.2秒、Set.has は約0.07ミリ秒でした。 件数が100倍になると includes の時間もおよそ100倍以上に伸び、Set.has はほぼ同じです。some が100万件で includes より短い時間になったのは、この環境・このデータ(整数の連番)での結果で、エンジンの最適化の効き方によって変わります。順位よりも「配列を順に見る方法は件数に比例して時間が伸びる」という傾向として読んでください。
一方、検索が1回だけなら、Set を作る時間のほうが長くなります。
| 件数 N | includes を1回(見つからない値) | new Set を作って has を1回 |
|---|---|---|
| 1万件 | 0.008 ms | 0.61 ms |
| 100万件 | 1.697 ms | 164.37 ms |
100万件でも includes 1回は約1.7ミリ秒です。数値は1台の環境での測定値で、実行環境によって変わります。
includesとSet.hasの選び方
| 状況 | 向いている方法 | 理由 |
|---|---|---|
| 数十〜数百件の配列 | includes | 読みやすく、時間の差は表に出ない |
| 大きな配列を1回だけ調べる | includes | Set を作る時間のほうが長い |
| 大きな配列を繰り返し調べる(ループの中、二重ループ) | 先に Set を作って has | 1回ごとの検索時間が件数に左右されない |
| 2つの大きな配列の共通部分・差分を取る | 片方を Set にして filter | a.filter(x => setB.has(x)) |
| オブジェクトを id で繰り返し引く | Map | byId.get(id) で要素そのものが取れる |
// 直す前:filter の中で includes(b が大きいと件数の掛け算で時間が伸びる)
const common = a.filter(x => b.includes(x));
// 直した後:b を Set にしてから調べる
const setB = new Set(b);
const common2 = a.filter(x => setB.has(x));
[1, 2, 3] と [2, 3, 4] で両方を実行し、どちらも [2, 3] になることを確認しました。結果は同じで、変わるのは大きな配列での所要時間です。
つまずきやすい点のチェックリスト
存在チェックが期待どおりに動かないときは、次の順に確かめると原因を絞り込めます。右の列は、この記事で実行して確かめた結果です。
| 確かめること | 確かめ方 | この記事での実行結果 |
|---|---|---|
| 配列の要素と探す値の型は同じか | typeof arr[0] と typeof value を出力する |
[1, 2, 3].includes('2') は false、includes(Number('2')) は true |
| indexOf の結果をそのまま if に入れていないか | !== -1 と比べているかを見る |
0 番目で見つかると false 側へ進む |
| オブジェクトを includes で探していないか | some や find に書き換える | users.includes({ id: 1 }) は false |
| 配列が undefined になっていないか | (list ?? []).includes(v) と書く |
undefined のとき false が返る(list?.includes(v) は undefined) |
| 配列の includes と文字列の includes を取り違えていないか | 対象が配列か文字列かを見る | ['apple'].includes('app') は false、'apple'.includes('app') は true |
| 空き要素が混ざっていないか | delete arr[1] や new Array(n) を使っていないかを見る |
delete のあとは [ 1, <1 empty item>, 3 ] になる |
| 大文字と小文字、前後の空白は同じか | trim() と toLowerCase() でそろえる |
['a'].includes('A') は false |
型の取り違えは、とくに画面からの入力やファイルから読んだ値で起こりやすい点です。配列を作る段階で map(Number) や map(String) を使って型をそろえておくと、あとの存在チェックをすべて includes だけで書けるようになります。
どのメソッドを選ぶかの判断表
| やりたいこと | 選ぶメソッド |
|---|---|
| 値(数値・文字列)が含まれるか | includes |
| 値の位置がほしい、その位置で削除や置き換えをする | indexOf |
| 最後に出てくる位置がほしい | lastIndexOf |
| NaN が含まれるか | includes(NaN) |
| 条件に合う要素があるか(オブジェクト配列を含む) | some |
| 条件に合う最初の要素がほしい | find |
| 条件に合う最後の要素がほしい | findLast |
| 条件に合う要素の位置がほしい | findIndex / findLastIndex |
| 条件に合う要素を全部ほしい | filter |
| 大きな配列で何度も存在チェックをする | Set の has |
| すべての要素が条件を満たすか | every |
flowchart TD
A[配列から探したい] --> B{探すのは値そのもの?}
B -->|はい 数値や文字列| C{ほしいのは?}
C -->|あるかどうか| D[includes]
C -->|位置| E[indexOf / lastIndexOf]
D --> D1{大きな配列で何度も調べる?}
D1 -->|はい| D2[Set を作って has]
B -->|いいえ 条件やオブジェクト| F{ほしいのは?}
F -->|あるかどうか| G[some]
F -->|最初の1件| H[find]
F -->|位置| I[findIndex]
F -->|全件| J[filter]
よくある質問
Q. includes と indexOf は、どちらが速いですか? A. 今回の測定では、1万件で includes 7.87ms・indexOf 6.36ms、100万件で 1231.61ms・1208.96ms(いずれも1000回の検索)と、ほぼ同じでした。どちらも配列を先頭から順に見るためです。速度で選ぶのではなく、真偽値がほしいなら includes、位置がほしいなら indexOf と、戻り値で選ぶのがおすすめです。検索回数が多くて時間が気になるときは Set.has に切り替えます。
Q. オブジェクトの配列に includes を使っても false になるのはなぜですか?
A. includes は、オブジェクトを「同じ参照かどうか」で比べるためです。users.includes({ id: 1 }) の { id: 1 } はその場で作られた新しいオブジェクトなので、中身が同じでも一致しません。users.some(u => u.id === 1) のように、比べたいプロパティを条件として書きます。
Q. find と filter はどう使い分けますか? A. 1件だけほしいなら find、条件に合うものを全部ほしいなら filter です。find は最初に見つかった時点で探すのをやめ、要素そのもの(無ければ undefined)を返します。filter は最後まで見て、配列(無ければ空の配列)を返します。存在チェックだけなら、true / false を返す some が読みやすくなります。
Q. 文字列の includes と配列の includes は同じものですか?
A. 名前は同じですが別のメソッドです。配列の includes は「要素として完全に一致するものがあるか」、文字列の includes は「部分文字列として含まれるか」を調べます。['apple'].includes('app') は false、'apple'.includes('app') は true になります。
まとめ
- 存在チェックは includes、位置がほしいときは indexOf。indexOf の結果は -1 と比べる
- NaN を見つけられるのは includes と Set.has。indexOf は -1 を返す。関数で探すなら
Number.isNaN - 空き要素は includes では undefined として見つかり、indexOf では見つからない。型違い("1" と 1)はどちらも一致しない
- オブジェクト配列は some・find・findIndex・filter で条件を書く。ネストしたプロパティには
?.を付ける - 重複チェックは Set の size と配列の length を比べる。id での重複の除去は Map
- いずれかを含むは some + includes、すべてを含むは every + includes。空の配列に対する every は true
- 大きな配列を繰り返し調べるなら Set.has。100万件・1000回の検索で includes 約1.2秒に対し Set.has は約0.07ミリ秒。1回だけなら includes で十分
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。