.filter()
.filter() は、配列から条件に一致する要素だけを抽出する組み込みメソッドです。
filter-example.ts
const numbers = [1, 2, 3, 4, 5];
const oddNumbers = numbers.filter(value => value % 2 === 1);
// oddNumbers: [1, 3, 5]
.find()
.find() は、配列から条件に一致する最初の要素を取り出します。条件に一致する要素がない場合は undefined を返します。
find-example.ts
const users = [
{id: '0000', name: 'Taro'},
{id: '0001', name: 'Jiro'},
{id: '0002', name: 'Saburo'}
];
const user = users.find(user => user.id === '0000');
// user: {id: '0000', name: 'Taro'}
.filter() と似ていますが、 条件に一致する要素が 1 つ見つかった時点で処理を終了する ので、処理に無駄がありません。
.filter() でも同じ処理はできますが、最初に 'Taro' を見つけても処理が終わらず、 'Jiro' や 'Saburo' にも絞り込み処理をしてしまいます。
以下のような書き方をしていませんか?
find-using-filter-example.ts
// よくない例:全ての要素を調べてしまう
const user = users.filter(user => user.id === '0000')[0];
// いい例:条件に一致する最初の要素が見つかった時点で処理を終了
const user = users.find(user => user.id === '0000');
.find() を使うことでパフォーマンス面が改善するだけでなく、「1 つ見つけたい」という目的が明確になり、.filter()[0] と比べて可読性も改善します。
!
条件に合う要素を配列の後ろから順に探したい場合は .findLast() が使えます。
条件に合う要素が配列の何番目にあるか探したい場合は .findIndex() や findLastIndex() が使えます。
単に一致する要素が何番目にあるか探したい場合は、高階関数を使わない .indexOf() や .lastIndexOf() を使うと簡単です。
.some()
.some() は、配列の要素のうち 少なくとも1つが条件を満たすかどうか を判定します。条件を満たす要素が1つでも見つかると true を返し、1つも見つからなければ false を返します。
some-example.ts
const numbers = [1, 2, 3, 4, 5];
const hasEvenNumber = numbers.some(num => num % 2 === 0);
// hasEvenNumber: true (2と4が偶数なので)
const users = [
{name: 'Taro', age: 27},
{name: 'Jiro', age: 25},
{name: 'Saburo', age: 22}
];
const hasAdult = users.some(user => user.age >= 18);
// hasAdult: true
条件に一致する要素が1つ見つかった時点で処理を終了する ので効率的です。
以下のような書き方をしていませんか?
some-using-filter-example.ts
// よくない例:全ての要素を調べてしまう
const hasAdult = users.filter(user => user.age >= 18).length > 0;
// 良い例:条件に一致する要素が見つかった時点で終了
const hasAdult = users.some(user => user.age >= 18);
!
単に特定の要素が含まれているかを確認したい場合は高階関数を使わない .includes() を使うと簡単です。
const fruits = ['apple', 'banana', 'cherry'];
const hasBanana = fruits.includes('banana');
// hasBanana: true
.every()
.every() は、配列の 全ての要素が条件を満たすかどうか を判定します。全ての要素が条件を満たせば true、1つでも満たさない要素があれば false を返します。
every-example.ts
const numbers = [2, 4, 6, 8];
const allEven = numbers.every(num => num % 2 === 0);
// allEven: true (全て偶数なので)
const users = [
{name: 'Taro', age: 22},
{name: 'Jiro', age: 20},
{name: 'Saburo', age: 17}
];
const allAdults = users.every(user => user.age >= 18);
// allAdults: false (Saburo が 17 歳で未成年なので)
条件を満たさない要素が1つ見つかった時点で処理を終了する ので、こちらも効率的です。
以下のような書き方をしていませんか?
every-using-filter-example.ts
// よくない例:全ての要素を調べてフィルタリングする
const allAdults = users.filter(user => user.age >= 18).length === users.length;
// 良い例:条件を満たさない要素が見つかった時点で終了
const allAdults = users.every(user => user.age >= 18);
まとめ
メソッド 用途 戻り値 早期終了
.filter() 条件に一致する要素を全て抽出 配列 なし
.find() 条件に一致する最初の要素を取得 要素 or undefined あり
.some() 条件に一致する要素が1つでもあるか判定 boolean あり
.every() 全ての要素が条件に一致するか判定 boolean あり
おわりに
配列操作では、目的に応じて適切なメソッドを選択することで、コードの可読性とパフォーマンスの両方を向上させることができます。
特に大きな配列を扱う場合、早期終了する .find()、.some()、.every() を適切に使い分けることで、無駄な処理を削減できます。
最初は慣れないかもしれませんが、これらのメソッドを使いこなせるようになると、より美しく効率的なJavaScriptコードを書けるようになります。ぜひ積極的に活用してみてください!
!
紹介したメソッド以外にも、.reduce()、.flat() など、便利な配列メソッドがたくさんあります。MDNのドキュメントを参考に、少しずつ覚えていきましょう。