Enumerable.​Select メソッド/ List<T>.Selectメソッドを利用する - すべての要素に対して処理を適用する - C#

Enumerable.​Select メソッドを利用して、Enumerable オブジェクトのすべての要素に対して処理を適用するコードを紹介します。

概要

Listなど、一つのオブジェクトに複数の値が格納される Collection型のオブジェクトですべての要素に対して処理を適用させたいことがあります。オーソドックスな方法としては forループや、foreachループを利用してひとつづつ要素を処理する方法があります。通常はこの記述で問題ありませんが適用させる処理のロジックを使いまわす場合や、よりコードをシンプルに記述したい場合など、ループ処理のコードをよりシンプルに記述したいこともあります。Enumerable オブジェクトの Selectメソッドを利用することで、ループのコードを無くしてシンプルなコードに記述できます。

プログラム例

今回は IEnumerable インターフェイスを実装しているListクラスを利用してSelectメソッドを利用するサンプルを紹介します。

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 SelectDemo
{
  public partial class FormListSelect : Form
  {
    public FormListSelect()
    {
      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("くじらケーキ");

      //List<string> ProcList = new List<string>(StrList.Select(select_proc));
      //List<string> ProcList = StrList.Select(select_proc).ToList<string>();

      IEnumerable<string> strenum = StrList.Select(select_proc);
      List<string> ProcList = strenum.ToList<string>();

      foreach (string t in ProcList) {
        textBox1.Text += t + "\r\n";
      }
    }

    private string select_proc(string value) {
      return "「" + value + "」";
    }

    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> strenum = StrList.Select(delegate(string value) { return "「" + value + "」"; });
      List<string> ProcList = strenum.ToList<string>();


      foreach (string t in ProcList) {
        textBox1.Text += t + "\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> strenum = StrList.Select((string value) => { return "「" + value + "」"; });
      List<string> ProcList = strenum.ToList<string>();

      foreach (string t in ProcList) {
        textBox1.Text += t + "\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> strenum = StrList.Select((value) => "「" + value + "」");
      List<string> ProcList = strenum.ToList<string>();

      foreach (string t in ProcList) {
        textBox1.Text += t + "\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> strenum = from value in StrList select "「" + value + "」";
      //StrList.Select((value) => "「" + value + "」");
      List<string> ProcList = strenum.ToList<string>();

      foreach (string t in ProcList) {
        textBox1.Text += t + "\r\n";
      }
    }
  }
}

実行結果と解説

上記のプロジェクトを実行します。下図のウィンドウが表示されます。

button1

button1をクリックすると下記のコードが実行されます。
先頭部分はListオブジェクトを作成しリストに文字列の値を追加するコードです。
値の追加後リストのSelect()メソッドを呼び出します。Selectメソッドの引数には select_procメソッドを与えます。StrListの各要素に対してselect_procメソッドが呼び出されます。リストの要素の値はselect_procメソッドの引数に与えられます。処理された値のリストはSelect関数の戻り値で帰ります。値をIEnumerable<string> オブジェクトである strenum オブジェクトに代入します。strenum オブジェクトからリストへの変換は EnumerableオブジェクトのToList()メソッドを呼び出して変換します。
処理後の値が格納されたProcList の要素をテキストボックスに表示します。
  private void button1_Click(object sender, EventArgs e)
  {
    List<string> StrList = new List<string>();
    StrList.Add("ぺんぎんクッキー");
    StrList.Add("らくだキャラメル");
    StrList.Add("しろくまアイス");
    StrList.Add("あひるサブレ");
    StrList.Add("くじらケーキ");

    //List<string> ProcList = new List<string>(StrList.Select(select_proc));
    //List<string> ProcList = StrList.Select(select_proc).ToList<string>();

    IEnumerable<string> strenum = StrList.Select(select_proc);
    List<string> ProcList = strenum.ToList<string>();

    foreach (string t in ProcList) {
      textBox1.Text += t + "\r\n";
    }
  }

  private string select_proc(string value) {
    return "「" + value + "」";
  }

今回は、わかりやすくするため、IEnumerable<string> strenum オブジェクトにいったん代入しましたが通常は下記のコードのように直接記述します。
    private void button1_Click(object sender, EventArgs e)
    {
      List<string> StrList = new List<string>();
      StrList.Add("ぺんぎんクッキー");
      StrList.Add("らくだキャラメル");
      StrList.Add("しろくまアイス");
      StrList.Add("あひるサブレ");
      StrList.Add("くじらケーキ");

      //List<string> ProcList = new List<string>(StrList.Select(select_proc));
      List<string> ProcList = StrList.Select(select_proc).ToList<string>();

      foreach (string t in ProcList) {
        textBox1.Text += t + "\r\n";
      }
    }

Select関数には Func<string, TResult> を与えるため、冗長になりますが、下記のコードで記述することも可能です。
  Func<string, string> ProcFunc = select_proc;
  IEnumerable<string> strenum = StrList.Select(ProcFunc);
  List<string> ProcList = strenum.ToList<string>();

[button1]をクリックします。要素の各値に対して、select_proc関数の処理が実行され、要素の文字列の前後が"「" "」" でくくられている値に変化していることが確認できます。

button2

[button2]クリック時には下記のコードが実行されます。[button1]のコードとの違いは、button1ではselectメソッドの引数にselect_proc() メソッドを与えましたが、button2ではメソッドを与えずに、Selectメソッドの引数に匿名メソッドを記述しています。匿名メソッドを利用すると、メソッドの実装を別のメソッドに分けた記述が不要になります。
  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> strenum = StrList.Select(delegate(string value) { return "「" + value + "」"; });
    List<string> ProcList = strenum.ToList<string>();

    foreach (string t in ProcList) {
      textBox1.Text += t + "\r\n";
    }
  }
プログラムを実行し[button2]をクリックします。要素の各値に対して、匿名メソッドの処理が実行され、要素の文字列の前後が"「" "」" でくくられている値に変化していることが確認できます。

button3

[button3]がクリックされた際のコードは下記になります。button2のコードの匿名メソッドをラムダ式に書き換えたコードになります。ラムダ式についてはこちらの記事も参照してください。
  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> strenum = StrList.Select((string value) => { return "「" + value + "」"; });
    List<string> ProcList = strenum.ToList<string>();

    foreach (string t in ProcList) {
      textBox1.Text += t + "\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> strenum = StrList.Select((value) => "「" + value + "」");
    List<string> ProcList = strenum.ToList<string>();

    foreach (string t in ProcList) {
      textBox1.Text += t + "\r\n";
    }
  }
プログラムを実行し[button4]をクリックします。要素の各値に対して、匿名メソッドの処理が実行され、要素の文字列の前後が"「" "」" でくくられている値に変化していることが確認できます。[button1]~[button4]まで同じ処理であることがわかります。

button5

[button5]をクリックした際に実行されるコードは下記になります。このコードは、Selectメソッドの呼び出しをメソッドの呼び出し形式で記述する方式からLINQの記述に変更したコードになります。select節の後ろに記述したラムダ式が先のコードの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> strenum = from value in StrList select "「" + value + "」";
    List<string> ProcList = strenum.ToList<string>();

    foreach (string t in ProcList) {
      textBox1.Text += t + "\r\n";
    }
  }

プログラムを実行し[button5]をクリックします。要素の各値に対して、匿名メソッドの処理が実行され、要素の文字列の前後が"「" "」" でくくられている値に変化していることが確認できます。[button1]~[button5]まで同じ処理であることがわかります。

著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
掲載日: 2018-09-17
iPentec all rights reserverd.