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組
業務でプログラミング(C#/VB/Python)を作っている。
挫折を何回も繰り返し、幾度の壁を乗り越えてきた。
乗り越えてきた事を忘れないように記録に残す。
同じ思いをしている人への情報提供になれたらと思う。
基本は初心者に向けたプログラムの情報を提供する。
コメント