【C#】List型とLINQ(Selectメソッド)

スポンサーリンク

LINQ(リンク)を使いこなす第3弾です。
特定の要素を抽出するメソッドであり、抽出した要素は加工/演算する事が可能なメソッドを紹介します。
Selectメソッドです。
この記事では、メソッド構文で紹介します。
クエリ構文は補足として最後に紹介しようと思います。

Selectメソッド

特定の要素を抽出するメソッドであり、抽出した要素は加工/演算する事が可能なメソッドです。
サンプルを紹介します。

要素を抽出する

要素を抽出する事がSelectメソッドにおいて、メインの機能です。
今回のサンプルでは、『リストに[学年と組]の構造体を登録して、そのリストから学年のみを抽出する』サンプルを紹介したいと思います。

定義

最初にNameSpaceが登録されていることを確認しましょう。

using System.Linq;

次にサンプルの為の構造体の定義です。

struct SchoolClass
{
    internal int Grade;    //年
    internal int ClassNo;  //組
}

そして、初期動作にリストを登録します。

List<SchoolClass> lstSchool = new List<SchoolClass>
{
    new SchoolClass{ Grade=1, ClassNo=1 },  //1年1組
    new SchoolClass{ Grade=3, ClassNo=2 },  //3年2組
    new SchoolClass{ Grade=1, ClassNo=2 },  //1年2組
    new SchoolClass{ Grade=2, ClassNo=2 },  //2年2組
    new SchoolClass{ Grade=2, ClassNo=1 },  //2年1組
    new SchoolClass{ Grade=3, ClassNo=1 },  //3年1組
};

1つ要素の抽出

本題である要素の抽出を行います。

//抽出
Console.WriteLine("学年を抽出");
List<int> lstSmpMethod = lstSchool.Select(x => x.Grade).ToList();
lstSmpMethod.ForEach(x => Console.WriteLine(x));  //結果 1,3,1,2,2,3

Selectメソッドを使う事で、リストが構造体であっても、指定の要素を抽出する事が出来ます
その為、シンプルにList<int>の時では、Selectメソッドで抽出する意味はありません。
しかし、次に紹介するすべての要素に加工や演算する時には使用します。

複数の要素を抽出

構造体の場合、複数の要素(項目)を抽出したいパタンもあると思います。
その場合は下記のようになります。
※今回のサンプルでは、そのまま同じリストを取得する結果になってしまいますが、構造体を変更してもよい。

//複数の抽出
Console.WriteLine("学年と組を抽出");
List<SchoolClass> lstSmpMethod4 = 
    lstSchool.Select(x => new SchoolClass 
    { 
        Grade= x.Grade,
        ClassNo= x.ClassNo
    }).ToList();
lstSmpMethod4.ForEach(x => Console.WriteLine(x.Grade + "年" + x.ClassNo + "組"));
//結果
//1年1組
//3年2組
//1年2組
//2年2組
//2年1組
//3年1組

ようは新しい構造体として、再度リストに登録するよう流れになります。

要素を加工/演算

適宜については先ほどのサンプルの定義を使用します(ここをクリック)

指定した1つの要素

Selectメソッドは、抽出がメインではありますが、オプションとして、指定した1つの要素 全てを加工/演算する事が可能です。

List<int> lstSample = new List<int> { 4, 16, 1, 2, 8 };

//全ての要素を10倍する
Console.WriteLine("リストの全ての要素を10倍する");
List<int> lstSmpMethod3 = lstSample.Select(x => x * 10).ToList();
lstSmpMethod3.ForEach(x => Console.WriteLine(x));  //結果 40,160,10,20,80

では、先ほどのサンプルのように「リストの中が[学年と組]のような構造体の場合」はどうなるのでしょうか?
このサンプルでは学年を抽出し、学年を10倍しようと思う。

//加工
Console.WriteLine("学年を抽出し、抽出した数値を10倍する");
List<int> lstSmpMethod2 = lstSchool.Select(x => x.Grade * 10).ToList();
lstSmpMethod2.ForEach(x => Console.WriteLine(x));  //結果 10,30,10,20,20,30

指定する要素が複数の場合

構造体を登録するリストクラスから、構造体から複数の項目(要素)を選択(抽出)し、その項目(要素)に対して演算してみます。
今回は、『学年を2倍、クラスを3倍にする』サンプルを作りたいと思います。

//複数の抽出し演算
Console.WriteLine("学年[x2]と組[x3]した状態で抽出");
List<SchoolClass> lstSmpMethod5 =
    lstSchool.Select(x => new SchoolClass
    {
        Grade = x.Grade * 2,
        ClassNo = x.ClassNo * 3
    }).ToList();
lstSmpMethod5.ForEach(x => Console.WriteLine(x.Grade + "年" + x.ClassNo + "組"));
//結果
//2年3組
//6年6組
//2年6組
//4年6組
//4年3組
//6年3組

まとめ

Selectメソッドの紹介でした。
Selectメソッドでは、指定した要素(項目)を選択して抽出し、必要とあれば加工します。
使い道とすれば、
データ元(今回はリスト)の中から、決まった要素を一括で抽出/加工したい時に使用
データ元の構造が複雑な時に必要な分だけ抽出/取得したい時に使用

自分的にSelectメソッドを何かに例えるとすると、
エクセルで、ある列を切り取り、別のシートに張り付けたイメージ』です。

使わないと慣れません。
実際にコードを書いて、実行してみて理解を深めていきましょう。

補足(クエリ構文で書いた場合)

//サンプル用のデータ 作成(構造体ver)
List<SchoolClass> lstSchool = new List<SchoolClass>
{
    new SchoolClass{ Grade=1, ClassNo=1 },  //1年1組
    new SchoolClass{ Grade=3, ClassNo=2 },  //3年2組
    new SchoolClass{ Grade=1, ClassNo=2 },  //1年2組
    new SchoolClass{ Grade=2, ClassNo=2 },  //2年2組
    new SchoolClass{ Grade=2, ClassNo=1 },  //2年1組
    new SchoolClass{ Grade=3, ClassNo=1 },  //3年1組
};

//サンプル用のデータ 作成(単純ver)
List<int> lstSample = new List<int> { 4, 16, 1, 2, 8 };
//抽出
Console.WriteLine("学年を抽出");
var lstSmpQuery1 =
    from x in lstSchool
    select x.Grade;
foreach (var q in lstSmpQuery1) Console.WriteLine(q);    
//結果 1,3,1,2,2,3

//複数の抽出
Console.WriteLine("学年と組を抽出");
var lstSmpQuery2 =
    from x in lstSchool
    select new
    {
        Grade = x.Grade,
        ClassNo = x.ClassNo
    };
foreach (var q in lstSmpQuery2) Console.WriteLine(q.Grade + "年" + q.ClassNo + "組");
//結果
//1年1組
//3年2組
//1年2組
//2年2組
//2年1組
//3年1組

//全ての要素を10倍する
Console.WriteLine("リストの全ての要素を10倍する");
var lstSmpQuery3 = 
    from x in lstSample
    select x * 10;
foreach (var q in lstSmpQuery3) Console.WriteLine(q);
//結果 40,160,10,20,80

//加工
Console.WriteLine("学年を抽出し、抽出した数値を10倍する");
var lstSmpQuery4 = 
    from x in lstSchool
    select x.Grade * 10;
foreach (var q in lstSmpQuery4) Console.WriteLine(q);
//結果 10,30,10,20,20,30

//複数の抽出し演算
Console.WriteLine("学年[x2]と組[x3]した状態で抽出");
var lstSmpQuery5 =
    from x in lstSchool
    select new SchoolClass
    {
        Grade = x.Grade * 2,
        ClassNo = x.ClassNo * 3
    };
foreach (var q in lstSmpQuery5) Console.WriteLine(q.Grade + "年" + q.ClassNo + "組");
//結果
//2年3組
//6年6組
//2年6組
//4年6組
//4年3組
//6年3組

//複数の抽出し演算(構造体を明示しない場合)
Console.WriteLine("学年[x2]と組[x3]した状態で抽出");
var lstSmpQuery5 =
    from x in lstSchool
    select new 
    {
        G = x.Grade * 2,
        C = x.ClassNo * 3
    };
foreach (var q in lstSmpQuery5) Console.WriteLine(q.G + "年" + q.C + "組");
//結果
//2年3組
//6年6組
//2年6組
//4年6組
//4年3組
//6年3組

コメント

タイトルとURLをコピーしました