読み込み中...

TypeScriptのfilterメソッド完全ガイド!12選の使い方とサンプル

TypeScriptのfilterメソッドを利用したコード例と説明 TypeScript
この記事は約25分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

TypeScriptは、大規模なプロジェクトでのJavaScriptの欠点を補完するために作られた言語であり、今や多くの開発者に支持されています。

特にTypeScriptの配列メソッドの中で、非常に役立つ「filterメソッド」について、本記事では深く掘り下げて解説します。

この記事を通じて、TypeScriptのfilterメソッドの基本から応用、さらに注意点まで、幅広く学んでいきましょう。

●TypeScriptのfilterメソッドとは

filterメソッドは、配列の要素をテストする関数を使用して、そのテストをパスするすべての要素から新しい配列を生成するためのものです。

この機能は、特定の条件を満たす要素のみを取得する際に非常に有効であり、コードの可読性や効率を向上させるための強力なツールとして利用されています。

○filterメソッドの基本

TypeScriptのfilterメソッドは、配列に対して特定のテスト関数を適用し、その関数を満たす要素のみを新しい配列として返します。

○filterメソッドの主な用途

filterメソッドは、様々なシチュエーションでのデータ処理において非常に役立ちます。

filterメソッドの主な用途をいくつか紹介します。

❶特定の条件を満たす要素のみを抽出する

上記の偶数の例のように、特定の条件を満たす要素だけを新しい配列として取得することができます。

❷不要なデータの除去

例えば、nullやundefinedなどの不要な値を持つ要素を配列から取り除く場合などに利用できます。

❸複数の配列を組み合わせて新しい配列を生成する

複数の配列に対してfilterメソッドを適用することで、それらの配列を組み合わせた新しい配列を生成することができます。

●filterメソッドの使い方

TypeScriptにおけるfilterメソッドは、配列の要素の中から特定の条件を満たすものだけを新しい配列として取り出すための非常に便利な方法です。

このメソッドは、JavaScriptのArray.prototype.filterメソッドをベースにしていますが、TypeScriptでは型の安全性を確保しつつ使用することができます。

ここでは、TypeScriptのfilterメソッドを使用したサンプルコードを紹介し、その使い方と特性について詳しく解説していきます。

○サンプルコード1:基本的なフィルタリング

まずは、TypeScriptのfilterメソッドの基本的な使い方から始めましょう。

下記のサンプルコードは、配列の中から偶数だけを取り出すシンプルな例です。

const numbers: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// 偶数だけを取り出す関数
const evenNumbers: number[] = numbers.filter((n) => n % 2 === 0);
console.log(evenNumbers);

このコードでは、まずnumbersという名前の配列を定義しています。

この配列の要素の中から、filterメソッドを使って偶数だけを取り出しています。

filterメソッドは、各要素に対してテスト関数を適用し、その結果がtrueとなる要素だけを新しい配列として返します。

上記のコードを実行すると、偶数だけが含まれた新しい配列[2, 4, 6, 8, 10]がコンソールに出力されます。

○サンプルコード2:オブジェクトのフィルタリング

TypeScriptを使ってデータの処理を行う際、配列に格納されたオブジェクトのフィルタリングは非常によく使われる操作の一つです。

特に、APIから取得したデータのうち、特定の条件を満たすものだけを取り出す際に非常に役立ちます。

ここでは、TypeScriptでのオブジェクトのフィルタリング方法を、具体的なサンプルコードを交えて解説します。

// サンプルのオブジェクト配列
const users = [
    { id: 1, name: "田中", age: 25, isActive: true },
    { id: 2, name: "鈴木", age: 30, isActive: false },
    { id: 3, name: "佐藤", age: 22, isActive: true },
    { id: 4, name: "高橋", age: 28, isActive: false }
];

// isActiveがtrueのユーザーだけを取得
const activeUsers = users.filter(user => user.isActive);

console.log(activeUsers);

このコードでは、usersというオブジェクトの配列を用意しています。

各オブジェクトは、id, name, age, isActiveというプロパティを持っています。

isActiveはユーザーがアクティブかどうかを示すブール値です。

filterメソッドを使用して、isActivetrueのユーザーだけを新しい配列として取得しています。

この処理を実行すると、結果として田中さんと佐藤さんのオブジェクトだけが含まれた新しい配列が生成されます。

このようなコードを実行すると、田中さんと佐藤さんのデータだけを含むオブジェクトの配列が出力されるでしょう。

このように、TypeScriptのfilterメソッドは、配列内のオブジェクトを特定の条件に基づいて簡単にフィルタリングすることができます。

○サンプルコード3:複数の条件を持つフィルタリング

TypeScriptにおけるfilterメソッドは、配列内の要素を特定の条件に基づいてフィルタリングするための高階関数です。

しかし、単一の条件だけでなく、複数の条件を組み合わせてフィルタリングを行うことも可能です。

ここでは、複数の条件を持つフィルタリングの方法を、具体的なサンプルコードを交えて解説します。

まず、次のような商品のリストを考えてみましょう。

type Product = {
  id: number;
  name: string;
  price: number;
  category: string;
};

const products: Product[] = [
  { id: 1, name: 'Tシャツ', price: 3000, category: '服' },
  { id: 2, name: 'ジーンズ', price: 10000, category: '服' },
  { id: 3, name: '冷蔵庫', price: 50000, category: '家電' },
  { id: 4, name: 'テレビ', price: 60000, category: '家電' },
  { id: 5, name: 'ノートPC', price: 150000, category: '家電' }
];

この商品のリストから、価格が30,000円以上の「家電」カテゴリの商品だけを抽出したいとします。

この要件を満たすフィルタリングを行うサンプルコードは次のようになります。

const filteredProducts = products.filter(product => 
  product.price >= 30000 && product.category === '家電'
);

このコードでは、filterメソッドを使って、価格が30,000円以上かつカテゴリが家電である商品を抽出しています。

条件は論理AND演算子(&&)を用いて結合されています。

このコードを実行すると、次のような結果が得られるでしょう。

冷蔵庫とテレビ、ノートPCという、価格が30,000円以上の家電カテゴリの商品が新たな配列に格納されます。

このように、複数の条件を持つフィルタリングは、条件を組み合わせることで様々な要件に応じたフィルタリングを行うことができます。

論理AND演算子だけでなく、論理OR演算子(||)を使用して、異なる条件のどちらかを満たす要素を抽出することもできます。

また、フィルタリングの条件は関数として記述されるため、動的に条件を生成することも可能です。

例えば、ユーザーからの入力を基に動的にフィルタリングを行いたい場合など、次のように関数を活用することで柔軟なフィルタリングが実現できます。

function createFilter(minPrice: number, targetCategory: string) {
  return (product: Product) => product.price >= minPrice && product.category === targetCategory;
}

const userMinPrice = 50000;  // ユーザーからの入力値とする
const userCategory = '家電';  // ユーザーからの入力値とする

const dynamicFilter = createFilter(userMinPrice, userCategory);
const dynamicFilteredProducts = products.filter(dynamicFilter);

このコードを実行すると、ユーザーの入力値に基づいて動的にフィルタリングが行われ、冷蔵庫、テレビ、ノートPCが抽出される結果になるでしょう。

○サンプルコード4:配列内の特定のプロパティをフィルタリング

TypeScriptにおけるfilterメソッドは非常に強力なツールです。

今回は、配列内のオブジェクトが持つ特定のプロパティに対してフィルタリングを行う方法を詳しく解説します。

考えられるシチュエーションとして、オンラインショップの商品リストがあり、特定のカテゴリーの商品だけを取得したい場面を想定します。

例として、次のような商品の配列があるとします。

type Product = {
    id: number;
    name: string;
    category: string;
    price: number;
};

const products: Product[] = [
    { id: 1, name: 'Tシャツ', category: 'ファッション', price: 1500 },
    { id: 2, name: 'パソコン', category: '電化製品', price: 100000 },
    { id: 3, name: '鉛筆', category: '文房具', price: 100 },
    { id: 4, name: '冷蔵庫', category: '電化製品', price: 50000 }
];

このコードでは、Productという型を定義し、productsという名前の配列に4つの商品データを格納しています。

特定のカテゴリー、例えば「電化製品」の商品だけを取得したい場合、filterメソッドを使用します。

const filteredProducts = products.filter(product => product.category === '電化製品');

このコードを実行すると、filteredProductsの配列には「パソコン」と「冷蔵庫」の2つの商品データが格納されます。

これは、filterメソッドが各商品のcategoryプロパティを調べ、'電化製品'と一致するものだけを新しい配列として返すためです。

filterメソッドの使い方は非常にシンプルで、引数として与えられるコールバック関数がtrueを返す要素だけが新しい配列に格納されます。

この方法を利用することで、様々な条件でのフィルタリングが可能となります。

例えば、特定の価格範囲の商品だけを取得する場合や、特定のキーワードを名前に含む商品を検索する場合など、要件に合わせてコールバック関数内の条件をカスタマイズすることができます。

今回の例でいうと、10,000円以上の商品だけを取得したい場合、次のように書くことができます。

const expensiveProducts = products.filter(product => product.price >= 10000);

このコードを実行すると、「パソコン」と「冷蔵庫」の2つの商品データがexpensiveProductsの配列に格納されます。

●filterメソッドの応用例

filterメソッドは非常に強力で、日常のコーディングで幅広い応用が可能です。

ここでは、その応用例をいくつかのサンプルコードを通じて詳しく解説します。

これらのコードを理解することで、あなたもTypeScriptでのデータ操作のスキルを一段と上げることができるでしょう。

○サンプルコード5:結果を新しい配列にマッピング

JavaScriptやTypeScriptでデータの操作を行う際、フィルタリングした結果をもとに新しい配列を作成するケースがよくあります。

このケースでは、filterメソッドを使った後に、mapメソッドを続けて使用することが一般的です。

ある学生のリストから合格点数以上の学生だけを抽出し、その学生の名前だけを新しい配列として取得する例を紹介します。

// 学生のデータのサンプル
interface Student {
  name: string;
  score: number;
}

const students: Student[] = [
  { name: '田中', score: 85 },
  { name: '佐藤', score: 72 },
  { name: '鈴木', score: 90 },
  { name: '山田', score: 78 },
  { name: '井上', score: 92 },
];

// 合格点数を設定
const PASS_SCORE = 80;

// 合格者の名前だけを新しい配列にマッピング
const passedStudentsNames = students
  .filter(student => student.score >= PASS_SCORE)
  .map(student => student.name);

console.log(passedStudentsNames);

このコードでは、まず学生のデータを格納するためのStudentインターフェースを定義しています。

次に、サンプルとして5人の学生のデータを持つstudents配列を定義しています。

合格点数としてPASS_SCOREを定義し、filterメソッドを使ってこの点数以上の学生だけを抽出します。

その後、mapメソッドを使用して、抽出された学生の名前だけを取得します。

このコードを実行すると、合格した学生の名前の配列、すなわち['田中', '鈴木', '井上']がコンソールに表示されます。

○サンプルコード6:他の高階関数との連携

TypeScriptにおいて、filterメソッドは配列を取り扱う際の強力なツールの一つです。

しかし、このfilterメソッドだけを使っても、より複雑なデータ操作やロジックを実装するのは難しいこともあります。

幸い、TypeScript(およびJavaScript)には他にも様々な高階関数が提供されており、これらをfilterメソッドと組み合わせることで、より洗練されたデータ操作を行うことができます。

下記のコードでは、filterメソッドを他の高階関数と連携して、複雑なデータ操作を行っています。

// サンプルのデータ
const products = [
  { id: 1, name: "シャツ", price: 1500, category: "ファッション" },
  { id: 2, name: "パンツ", price: 2000, category: "ファッション" },
  { id: 3, name: "鉛筆", price: 100, category: "文房具" },
  { id: 4, name: "ノート", price: 300, category: "文房具" }
];

// 価格が1000円以上の商品のみを抽出し、その商品名を新しい配列に格納する
const expensiveProductNames = products
  .filter(product => product.price >= 1000)
  .map(product => product.name);

console.log(expensiveProductNames);

このコードでは、まずfilterメソッドを使って価格が1000円以上の商品のみを抽出しています。

その後、mapメソッドを用いて、抽出された商品の名前のみを新しい配列に格納しています。

実行すると、expensiveProductNamesという配列には["シャツ", "パンツ"]という結果が格納されることになります。

これは、価格が1000円以上の商品の名前だけを抽出した結果となります。

○サンプルコード7:特定の条件下での値の変更

TypeScriptを使用する際、filterメソッドは非常に便利な配列のメソッドの1つです。

しかし、filterメソッドだけでなく、mapやreduceといった他の高階関数と組み合わせることで、さらに強力なデータ操作を実現できます。

今回のトピックである「特定の条件下での値の変更」では、filterメソッドを使用して特定の条件を満たす要素を抽出し、その後で特定の操作を適用する方法を解説します。

例として、次のような数値の配列が考えられます。

let numbers = [1, 2, 3, 4, 5, 6];

この配列から、例えば偶数だけを抜き出し、それぞれの数値を2倍にしたいとしましょう。

このコードではfilterメソッドを使って偶数を抽出し、続いてmapメソッドを用いて各要素を2倍にしています。

let doubledEvens = numbers.filter(n => n % 2 === 0).map(n => n * 2);
console.log(doubledEvens);

このコードを実行すると、まずfilterメソッドが配列numbers内の偶数だけを新しい配列として返します。

その後、mapメソッドが各偶数を2倍にして新しい配列を返します。

そのため、最終的なdoubledEvensの内容は [4, 8, 12] となります。

このように、filterメソッドと他の高階関数を組み合わせることで、配列の要素を効率的に操作できます。

また、この手法はオブジェクトの配列に対しても適用可能です。

例えば、次のようなオブジェクトの配列を考えます。

let students = [
  { name: "太郎", score: 85 },
  { name: "次郎", score: 92 },
  { name: "三郎", score: 78 },
];

この中から、scoreが90点以上の学生のみを抜き出し、その名前を大文字にしたい場合、次のようにコードを記述します。

let highScoreStudents = students
  .filter(student => student.score >= 90)
  .map(student => ({ ...student, name: student.name.toUpperCase() }));
console.log(highScoreStudents);

このコードを実行すると、highScoreStudentsの内容は [{ name: “次郎”, score: 92 }] となります。

このように、filterメソッドを使って特定の条件を満たす要素を選択し、その後の処理で値を変更することができます。

○サンプルコード8:データのグルーピング

TypeScriptを用いたデータ処理の際、配列の要素をグルーピングする場面がしばしばあります。

例えば、オブジェクトの配列があるとき、特定のキーに基づいてデータをグループ化したい場面が考えられます。

ここでは、filterメソッドを利用して、データのグルーピングを行う方法を詳しく解説します。

まず、基本的なサンプルコードを見てみましょう。

// ユーザーデータのサンプル
type User = {
    id: number;
    name: string;
    age: number;
    city: string;
};

const users: User[] = [
    { id: 1, name: "Taro", age: 25, city: "Tokyo" },
    { id: 2, name: "Hanako", age: 22, city: "Osaka" },
    { id: 3, name: "Jiro", age: 25, city: "Tokyo" },
    { id: 4, name: "Yoko", age: 22, city: "Osaka" },
];

// グルーピングの関数
function groupByCity(users: User[]): Record<string, User[]> {
    return users.reduce((acc, user) => {
        if (!acc[user.city]) {
            acc[user.city] = [];
        }
        acc[user.city].push(user);
        return acc;
    }, {} as Record<string, User[]>);
}

const groupedUsers = groupByCity(users);
console.log(groupedUsers);

このコードでは、Userという型を定義しており、その配列をグルーピングする関数groupByCityを作成しています。

関数内では、reduceメソッドを使って、都市ごとにユーザーをグルーピングしています。

最終的なgroupedUsersの結果を出力すると、都市ごとに配列が生成されることがわかります。

このコードを実行すると、次のような結果が得られます。都市名をキーとして、それに紐づくユーザーの配列が格納されています。

{
    Tokyo: [
        { id: 1, name: "Taro", age: 25, city: "Tokyo" },
        { id: 3, name: "Jiro", age: 25, city: "Tokyo" }
    ],
    Osaka: [
        { id: 2, name: "Hanako", age: 22, city: "Osaka" },
        { id: 4, name: "Yoko", age: 22, city: "Osaka" }
    ]
}

●注意点と対処法

TypeScriptのfilterメソッドは非常に便利であり、さまざまな状況で利用されています。

しかし、この便利さゆえに、特定のシチュエーションやデータに対して不適切に使用されると、思わぬ問題やバグの原因となることがあります。

それでは、filterメソッドを使用する際の主な注意点とそれに対する対処法について解説します。

○サンプルコード9:空の配列をフィルタリングする際の注意点

filterメソッドを使用して空の配列をフィルタリングする場合、何も出力されないのは自明です。

しかし、この状態が予期せずに発生した場合、エラーとして検知されにくい場合があります。

このコードでは、数字の配列から奇数だけを取り出すシンプルなフィルタリングを行います。

const numbers = [];
const oddNumbers = numbers.filter(num => num % 2 !== 0);
console.log(oddNumbers);

このコードを実行すると、oddNumbersは空の配列[]となります。

これはnumbersが最初から空だったためです。

しかしながら、この結果は予期せずに空の配列がフィルタリングされた場合、エラーの原因となります。

例えば、外部からデータを取得するような場面で、データの取得に失敗し、空の配列が返された場合、この結果はユーザーにとって意図しないものとなるでしょう。

対処法としては、フィルタリング前に配列の長さを確認し、空の場合は適切なエラーメッセージを表示する、あるいは別のアクションを実行するといった処理を追加することを考慮すべきです。

if (numbers.length === 0) {
    console.log('配列が空です。データを確認してください。');
} else {
    const oddNumbers = numbers.filter(num => num % 2 !== 0);
    console.log(oddNumbers);
}

このコードを実行すると、「配列が空です。データを確認してください。」というメッセージが出力されます。

これにより、空の配列が原因での問題を早期に検知し、対応することが可能となります。

○サンプルコード10:filterメソッドのパフォーマンスに関する注意点

TypeScriptやJavaScriptで配列の要素をフィルタリングする際、filterメソッドは非常に便利です。

しかしながら、大量のデータを扱う場合や頻繁にフィルタリングを行う場合には、パフォーマンスの面で気をつけるべき点があります。

この章では、filterメソッドのパフォーマンスに関する注意点と、それを踏まえた最適な使用方法をサンプルコードと共に解説していきます。

まず、下記のサンプルコードは10万件のデータを持つ配列から、ある条件を満たす要素のみをフィルタリングする例です。

// 10万件のデータを生成
const data = Array.from({ length: 100000 }, (_, index) => index);

// 偶数のみをフィルタリング
const filteredData = data.filter(item => item % 2 === 0);

このコードでは、0から99999までの10万件のデータを生成し、その中から偶数のみをフィルタリングしています。

しかし、これだけのデータをフィルタリングする場合、filterメソッドは10万回の処理を行う必要があります。

もし、このようなフィルタリングを頻繁に行う場合、特にリアルタイムなアプリケーションでの利用を考えると、パフォーマンスの低下が考えられます。

この問題を解決するための一つの方法は、filterメソッドの使用回数を減らすことです。

たとえば、前回のフィルタリング結果をキャッシュしておき、データに変更があった場合のみ再度フィルタリングを行うという方法が考えられます。

また、filterメソッドの代わりにforループを使用することで、条件に応じて処理を早めに終了させるという方法もあります。

const filteredData = [];
for (let i = 0; i < data.length; i++) {
    if (data[i] % 2 === 0) {
        filteredData.push(data[i]);
    }
}

このコードを実行すると、やはり偶数のデータのみがfilteredDataに格納されます。

ただし、filterメソッドを使用する場合と異なり、条件に一致する要素を見つけた時点で処理を終了させることができます。

●カスタマイズ方法

TypeScriptのfilterメソッドは非常に柔軟性が高く、独自のカスタマイズが可能です。

ここでは、カスタムフィルタリング関数の作成について、サンプルコードとともに詳しく解説します。

○サンプルコード11:カスタムフィルタリング関数の作成

下記のサンプルコードでは、独自のフィルタリング関数を使って、配列の中の特定の要素を取得しています。

type User = {
    id: number;
    name: string;
    age: number;
};

// カスタムフィルタ関数
function customFilter(users: User[], condition: (user: User) => boolean): User[] {
    return users.filter(condition);
}

const users: User[] = [
    { id: 1, name: "Taro", age: 20 },
    { id: 2, name: "Hanako", age: 25 },
    { id: 3, name: "Jiro", age: 23 },
    { id: 4, name: "Sachiko", age: 28 }
];

// 24歳以下のユーザーを取得
const filteredUsers = customFilter(users, user => user.age <= 24);
console.log(filteredUsers);

このコードでは、まずUserという型を定義しています。

そして、独自のフィルタリング関数customFilterを定義しています。

この関数は、配列と条件となるコールバック関数を受け取り、その条件に合致する要素のみを取得します。

実際のデータとしてusers配列を用意し、この配列から24歳以下のユーザーだけを取得する例を示しています。

このコードを実行すると、TaroとJiroの情報がコンソールに表示されます。

独自のフィルタリング関数を作成することで、複雑な条件や繰り返し使用する条件を効率的に処理することができます。

○サンプルコード12:filterメソッドを拡張するテクニック

JavaScriptやTypeScriptの配列のメソッドの中で、filterメソッドは非常に便利で頻繁に使用されます。

しかし、特定の処理を行いたい場合に、このメソッドだけでは不十分だと感じることもあるかと思います。

そのような時に、filterメソッドをカスタマイズや拡張することで、さらに応用的なフィルタリングを行うことができます。

このセクションでは、TypeScriptのfilterメソッドを拡張する一例として、配列の中の重複する要素を取り除く拡張を考えてみます。

通常のfilterメソッドだけでは少々難しいこの操作を、拡張を通じて簡単に行えるようにします。

// TypeScriptの配列のプロトタイプにメソッドを追加する
Array.prototype.filterUnique = function<T>(this: T[]): T[] {
  return this.filter((value, index, self) => {
    return self.indexOf(value) === index;
  });
}

// 使用例
const numbers = [1, 2, 3, 2, 1, 4, 5, 4];
const uniqueNumbers = numbers.filterUnique();
console.log(uniqueNumbers);  // [1, 2, 3, 4, 5]

このコードでは、まずArrayのプロトタイプにfilterUniqueという新しいメソッドを追加しています。

そして、この新しいメソッドの中で、通常のfilterメソッドを使用して、配列の中の重複する要素を取り除く処理を行っています。

具体的には、filterメソッドのコールバック関数の中で、現在の要素が配列内で最初に現れる位置と、現在の要素の位置が一致するかどうかを確認しています。

もし一致していれば、その要素は配列内で一度しか現れない、すなわち重複していないと判断することができます。

上記のコードを実行すると、uniqueNumbersという変数には[1, 2, 3, 4, 5]という、重複のない配列が格納されることになります。

まとめ

TypeScriptのfilterメソッドは、配列の要素を簡単にフィルタリングするための強力なツールとして、初心者から中級者まで多くの開発者に利用されています。

この記事では、filterメソッドの基本から応用、さらには注意点やカスタマイズ方法に至るまで、詳細にわたって解説を行いました。

今後の開発活動においても、本記事で学んだ知識とテクニックを活かし、filterメソッドを最大限に活用してください。