Enumerable.Where メソッドを利用して、Enumerable オブジェクトの要素に対して条件に一致する要素を抜き出すコードを紹介します。
概要
Listなど、一つのオブジェクトに複数の値が格納される Collection型のオブジェクトですべての要素から条件に一致する要素を抽出したいことがあります。オーソドックスな方法としては forループやforeachループを利用してひとつずつ要素を条件判定して抽出方法があります。通常はこの記述で問題ありませんが適用させる処理のロジックを使いまわす場合や、よりコードをシンプルに記述したい場合など、ループ処理のコードを無くし、よりシンプルに記述したいこともあります。Enumerable オブジェクトの Where メソッドを利用することでループ処理を無くしたシンプルなコードを記述できます。
プログラム例
今回は IEnumerable インターフェイスを実装しているListクラスを利用してWhere メソッドを利用するサンプルを紹介します。
UI
下図のUIを作成します。複数行のテキストボックスにボタンを5つ配置します。
コード
下記のコードを記述します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WhereDemo
{
public partial class FormListWhere : Form
{
public FormListWhere()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
List<string> StrList = new List<string>();
StrList.Add("シンプルチェア");
StrList.Add("ソリッドテーブル");
StrList.Add("ウッドデスク");
StrList.Add("コンフォートベッド");
StrList.Add("ブラウンチェア");
IEnumerable<string> tempenum = StrList.Where(where_proc);
List<string> ResultList = tempenum.ToList();
foreach (string s in ResultList) {
textBox1.Text += s + "\r\n";
}
}
private bool where_proc(string value) {
if (value.IndexOf("チェア") >= 0) {
return true;
}
else {
return false;
}
}
private void button2_Click(object sender, EventArgs e)
{
List<string> StrList = new List<string>();
StrList.Add("シンプルチェア");
StrList.Add("ソリッドテーブル");
StrList.Add("ウッドデスク");
StrList.Add("コンフォートベッド");
StrList.Add("ブラウンチェア");
IEnumerable<string> tempenum = StrList.Where(delegate(string value) {
if (value.IndexOf("チェア") >= 0) {
return true;
}
else {
return false;
}
});
List<string> ResultList = tempenum.ToList();
foreach (string s in ResultList) {
textBox1.Text += s + "\r\n";
}
}
private void button3_Click(object sender, EventArgs e)
{
List<string> StrList = new List<string>();
StrList.Add("シンプルチェア");
StrList.Add("ソリッドテーブル");
StrList.Add("ウッドデスク");
StrList.Add("コンフォートベッド");
StrList.Add("ブラウンチェア");
IEnumerable<string> tempenum = StrList.Where((string value)=>{
if (value.IndexOf("チェア") >= 0) {
return true;
}
else {
return false;
}
});
List<string> ResultList = tempenum.ToList();
foreach (string s in ResultList) {
textBox1.Text += s + "\r\n";
}
}
private void button4_Click(object sender, EventArgs e)
{
List<string> StrList = new List<string>();
StrList.Add("シンプルチェア");
StrList.Add("ソリッドテーブル");
StrList.Add("ウッドデスク");
StrList.Add("コンフォートベッド");
StrList.Add("ブラウンチェア");
IEnumerable<string> tempenum = StrList.Where((value) => value.IndexOf("チェア") >= 0);
List<string> ResultList = tempenum.ToList();
foreach (string s in ResultList) {
textBox1.Text += s + "\r\n";
}
}
private void button5_Click(object sender, EventArgs e)
{
List<string> StrList = new List<string>();
StrList.Add("シンプルチェア");
StrList.Add("ソリッドテーブル");
StrList.Add("ウッドデスク");
StrList.Add("コンフォートベッド");
StrList.Add("ブラウンチェア");
IEnumerable<string> tempenum = from value in StrList where value.IndexOf("チェア") >= 0 select value;
List<string> ResultList = tempenum.ToList();
foreach (string s in ResultList) {
textBox1.Text += s + "\r\n";
}
}
}
}
実行結果と解説
上記のプロジェクトを実行します。下図のウィンドウが表示されます。
button1
[button1]をクリックすると下記のコードが実行されます。
先頭部分はListオブジェクトを作成しリストに文字列の値を追加するコードです。値の追加後に、Where() メソッドを呼び出します。Whereメソッドの引数には、where_procメソッドを与えます。where_procメソッドは Func(string,bool) 型のメソッドであり、戻り値にBoolを返すメソッドです。StrListの各要素に対して、where_proc()メソッドが呼び出されます。要素の値は、where_procメソッドの第一引数 value に与えられます。where_procメソッドの戻り値がtrueであった場合は、条件に合致するため、抽出結果に含まれます。一方戻り値がfalseであった場合は結果には含まれません。
今回のwhere_proc()メソッドのコードは要素の値に「チェア」の文字列が含まれる場合のみ結果にtrueを返し、要素を結果に含む動作となります。「シンプルチェア」「ブラウンチェア」の要素が結果に含まれます。
結果はWhereメソッドの戻り値として返ります。処理後に foreachループで結果のリストに含まれる要素の値をテキストボックスに表示します。
private void button1_Click(object sender, EventArgs e)
{
List<string> StrList = new List<string>();
StrList.Add("シンプルチェア");
StrList.Add("ソリッドテーブル");
StrList.Add("ウッドデスク");
StrList.Add("コンフォートベッド");
StrList.Add("ブラウンチェア");
IEnumerable<string> tempenum = StrList.Where(where_proc);
List<string> ResultList = tempenum.ToList();
foreach (string s in ResultList) {
textBox1.Text += s + "\r\n";
}
}
private bool where_proc(string value) {
if (value.IndexOf("チェア") >= 0) {
return true;
}
else {
return false;
}
}
[button1]をクリックします。テキストボックスに「シンプルチェア」と「ブラウンチェア」の文字列が表示されます。where_proc() メソッドに実装した条件判定処理が動作してリストから条件に合致する要素を抽出できていることがわかります。
button2
[button2]クリック時には下記のコードが実行されます。[button1]のコードとの違いは、button1ではWhereメソッドの引数にwhere_proc() メソッドを与えましたが、button2ではメソッドを与えずに、Whereメソッドの引数に匿名メソッドを記述しています。匿名メソッドを利用すると、メソッドの実装を別のメソッドに分けた記述が不要になります。
private void button2_Click(object sender, EventArgs e)
{
List<string> StrList = new List<string>();
StrList.Add("シンプルチェア");
StrList.Add("ソリッドテーブル");
StrList.Add("ウッドデスク");
StrList.Add("コンフォートベッド");
StrList.Add("ブラウンチェア");
IEnumerable<string> tempenum = StrList.Where(delegate(string value) {
if (value.IndexOf("チェア") >= 0) {
return true;
}
else {
return false;
}
});
List<string> ResultList = tempenum.ToList();
foreach (string s in ResultList) {
textBox1.Text += s + "\r\n";
}
}
プログラムを実行し[button2]をクリックします。テキストボックスに「シンプルチェア」と「ブラウンチェア」の文字列が表示されます。コードに記述した条件で要素が抽出できていることが確認できます。
button3
[button3]のコードは下記になります。button2のコードでは、Where() メソッドに匿名メソッドを与えていましたが、ラムダ式での記述に書き換えています。
private void button3_Click(object sender, EventArgs e)
{
List<string> StrList = new List<string>();
StrList.Add("シンプルチェア");
StrList.Add("ソリッドテーブル");
StrList.Add("ウッドデスク");
StrList.Add("コンフォートベッド");
StrList.Add("ブラウンチェア");
IEnumerable<string> tempenum = StrList.Where((string value)=>{
if (value.IndexOf("チェア") >= 0) {
return true;
}
else {
return false;
}
});
List<string> ResultList = tempenum.ToList();
foreach (string s in ResultList) {
textBox1.Text += s + "\r\n";
}
}
プログラムを実行し[button3]をクリックします。テキストボックスに「シンプルチェア」と「ブラウンチェア」の文字列が表示されます。
button4
[button4]がクリックされると下記のコードが実行されます。button3のコードのラムダ式はステートメント形式のラムダ式でしたが、これを式形式のラムダ式に書き換えています。
private void button4_Click(object sender, EventArgs e)
{
List<string> StrList = new List<string>();
StrList.Add("シンプルチェア");
StrList.Add("ソリッドテーブル");
StrList.Add("ウッドデスク");
StrList.Add("コンフォートベッド");
StrList.Add("ブラウンチェア");
IEnumerable<string> tempenum = StrList.Where((value) => value.IndexOf("チェア") >= 0);
List<string> ResultList = tempenum.ToList();
foreach (string s in ResultList) {
textBox1.Text += s + "\r\n";
}
}
プログラムを実行し[button4]をクリックします。テキストボックスに「シンプルチェア」と「ブラウンチェア」の文字列が表示されます。[button1]~[button4]まで同じ処理であることがわかります。
button5
[button5]をクリックした際に実行されるコードは下記になります。このコードは、Whereメソッドの呼び出しをメソッドの呼び出し形式で記述する方式からLINQの記述に変更したコードになります。where 節の後ろに記述したラムダ式が抽出条件の式となります。また、結果となる変数をselect節で指定しています。LINQについては
こちらの記事を参照してください。
private void button5_Click(object sender, EventArgs e)
{
List<string> StrList = new List<string>();
StrList.Add("シンプルチェア");
StrList.Add("ソリッドテーブル");
StrList.Add("ウッドデスク");
StrList.Add("コンフォートベッド");
StrList.Add("ブラウンチェア");
IEnumerable<string> tempenum = from value in StrList where value.IndexOf("チェア") >= 0 select value;
List<string> ResultList = tempenum.ToList();
foreach (string s in ResultList) {
textBox1.Text += s + "\r\n";
}
}
プログラムを実行し[button5]をクリックします。テキストボックスに「シンプルチェア」と「ブラウンチェア」の文字列が表示されます。[button1]~[button5]まで同じ処理であることがわかります。
このページのキーワード
- Enumerable.Where メソッド / List<T>.Where メソッドを利用する - 指定した条件を満たす集合を取得する
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2024-01-07
作成日: 2018-09-17