Whereとフィルタリング
一致する要素を選択します。
「Whereとフィルタリング」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全4レッスンが含まれています。
Whereが行うこと
Where は、LINQ の中心的なフィルタリング演算子です。bool を返す関数である述語を受け取り、その条件を満たす要素だけを返します。
System.Linq に定義されており、任意の IEnumerable<T> に対して使用できます。元のシーケンスを変更するのではなく、新しいシーケンスを返します。
using System;
using System.Linq;
using System.Collections.Generic;
var nums = new List<int> { 1, 2, 3, 4, 5, 6 };
var evens = nums.Where(n => n % 2 == 0);
Console.WriteLine(string.Join(", ", evens));述語ラムダ
Where の引数は、n => condition のようなラムダ式です。パラメーターは各要素を表し、本体は true または false に評価される必要があります。
true を返すとその要素は残り、false を返すと除外されます。任意のブール式を使用できます。
using System;
using System.Linq;
string[] words = { "apple", "fig", "banana", "kiwi" };
var shortWords = words.Where(w => w.Length <= 4);
Console.WriteLine(string.Join(", ", shortWords));クエリ構文形式
LINQ には、SQL のように読めるクエリ構文があります。where 句でフィルタリングし、select 句で射影します。
クエリ構文は同じメソッド呼び出しにコンパイルされるため、from x in src where ... select x は src.Where(...) と同じです。読みやすいほうを使ってください。
using System;
using System.Linq;
int[] scores = { 40, 75, 90, 55, 88 };
var passing = from s in scores
where s >= 60
select s;
Console.WriteLine(string.Join(", ", passing));条件を組み合わせる
1つの述語内で、&& と || を使って複数のチェックを組み合わせられます。これにより、関連するフィルタリングを1回の処理にまとめられます。
演算子を混在させる場合は、通常のブール式と同じように、括弧を使うと読みやすくなります。
using System;
using System.Linq;
using System.Collections.Generic;
var ages = new List<int> { 12, 17, 21, 35, 64, 70 };
var adults = ages.Where(a => a >= 18 && a < 65);
Console.WriteLine(string.Join(", ", adults));Where呼び出しをチェーンする
複数の Where 呼び出しをチェーンできます。各呼び出しは直前の結果をフィルタリングするため、条件は論理 AND として組み合わされます。
大きな述語を1つ書くよりもチェーンのほうが明確な場合があります。また、異なる場所で作成したフィルターを組み合わせることもできます。
using System;
using System.Linq;
int[] data = { 3, 8, 15, 22, 27, 40 };
var result = data.Where(n => n > 5)
.Where(n => n % 2 == 0);
Console.WriteLine(string.Join(", ", result));インデックス付きのWhere
Where のオーバーロードの1つでは、要素の0始まりのインデックスを2番目のラムダパラメーターとして取得できます。位置に基づいてフィルタリングする場合に便利です。
たとえば、要素を1つおきに残したり、インデックスを使って先頭の要素をスキップしたりできます。
using System;
using System.Linq;
string[] items = { "a", "b", "c", "d", "e" };
var evenIdx = items.Where((val, idx) => idx % 2 == 0);
Console.WriteLine(string.Join(", ", evenIdx));オブジェクトをフィルタリングする
フィルタリングは、オブジェクトのコレクションで特に効果を発揮します。述語から各要素の任意のプロパティを読み取れます。
これにより、「この都市に住む顧客」「しきい値を超える注文」といったビジネスルールを、宣言的に表現できます。
using System;
using System.Linq;
using System.Collections.Generic;
record Product(string Name, decimal Price);
var list = new List<Product> {
new("Pen", 1.5m), new("Lamp", 20m), new("Mug", 8m) };
var cheap = list.Where(p => p.Price < 10);
foreach (var p in cheap) Console.WriteLine(p.Name);遅延実行
Where は遅延実行を使用します。定義した時点では実行されず、シーケンスを反復処理したとき(たとえば foreach や ToList の呼び出し時)にだけ実行されます。
そのため、反復処理を始める前に元のシーケンスを変更すると、その変更が結果に反映されます。
using System;
using System.Linq;
using System.Collections.Generic;
var src = new List<int> { 1, 2 };
var q = src.Where(n => n > 1);
src.Add(5);
Console.WriteLine(string.Join(", ", q));再評価のコスト
フィルタリングは遅延実行されるため、同じクエリを2回反復すると、述語も2回実行されます。高コストな述語や変化し続けるデータソースを扱う場合は、意外な結果になることがあります。
安定した再利用可能なスナップショットが必要な場合は、後のレッスンで扱う ToList を使って1回だけ具体化してください。
using System;
using System.Linq;
int calls = 0;
int[] nums = { 1, 2, 3 };
var q = nums.Where(n => { calls++; return n > 1; });
foreach (var _ in q) { }
foreach (var _ in q) { }
Console.WriteLine(calls);フィルタリングしてからカウントする
よくあるパターンは、フィルタリングしてから一致した数を確認することです。Count には述語を直接渡せるため、フィルタリングとカウントをまとめて実行できます。
count.Count(p => cond) は seq.Where(p => cond).Count() と同等ですが、より簡潔に意図を表せます。
using System;
using System.Linq;
int[] grades = { 55, 80, 42, 91, 67 };
int passed = grades.Count(g => g >= 60);
Console.WriteLine($"Passed: {passed}");空の結果でも問題ありません
述語を満たす要素がない場合、Where は単に空のシーケンスを返します。null になることはありません。
そのため、フィルターを安全にチェーンできます。空の結果は、特別な処理をしなくても後続の演算子に渡せます。
using System;
using System.Linq;
int[] nums = { 1, 2, 3 };
var big = nums.Where(n => n > 100);
Console.WriteLine($"Count: {big.Count()}");理解度チェック
遅延実行についての理解度を確認しましょう。
まとめ
Where はブール値を返す述語でシーケンスをフィルタリングし、新しい IEnumerable を返します。インデックスを取得するオーバーロードがあり、チェーンしたり &&/|| と組み合わせたりできます。また、オブジェクトのプロパティを使ってフィルタリングすることもできます。
重要なのは、Where が遅延実行される点です。反復時に実行されるため、再度反復すると再評価されます。次は Select を使って、残すデータの形を整えます。
よくある質問
「Whereとフィルタリング」レッスンは無料ですか?
はい。「Whereとフィルタリング」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全4レッスンが含まれています。
「Whereとフィルタリング」で何を学びますか?
一致する要素を選択します。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
C# Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「Whereとフィルタリング」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このC# Academyレッスンでコードを書いて実行できますか?
はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Whereとフィルタリング
- SelectとProjection
- OrderByとグループ化
- 集計とToList