前回の記事はこちらになります
https://meimaru.hatenablog.com/entry/2020/05/23/%E3%80%90C%23%E3%80%91LINQ%E3%81%AB%E6%85%A3%E3%82%8C%E3%82%8B1%EF%BD%9ELINQ%E3%81%A8%E3%81%AF%EF%BD%9Emeimaru.hatenablog.com
今回はLINQのメソッドをいろいろ使ってみようと思います。
前方・後方・部分一致検索
using System; using System.Linq; namespace Test.LINQ { class SandBox { public static void Main(string[] args) { var sfcSoftTable = new SfcSoftTable(); var softTitles = sfcSoftTable.SoftTable.Where(val => val.Title.StartsWith("星の")) .OrderByDescending(val => val.Price) .Select(val => val.Title + " 価格:" + val.Price); var softTitles2 = sfcSoftTable.SoftTable.Where(val => val.Title.EndsWith("デラックス")) .OrderByDescending(val => val.Price) .Select(val => val.Title + " 価格:" + val.Price); var softTitles3 = sfcSoftTable.SoftTable.Where(val => val.Title.Contains("カービィ")) .OrderByDescending(val => val.Price) .Select(val => val.Title + " 価格:" + val.Price); Console.WriteLine("前方一致:StartsWith"); foreach (var title in softTitles) { Console.WriteLine(title); } Console.WriteLine("-------------------------------------"); Console.WriteLine("後方一致:EndsWith"); foreach (var title in softTitles2) { Console.WriteLine(title); } Console.WriteLine("-------------------------------------"); Console.WriteLine("部分一致:Contains"); foreach (var title in softTitles3) { Console.WriteLine(title); } } } }
検索でおなじみのStartsWith、EndsWith、Containsを使い、
- タイトルが「星の」から始まるソフト
- タイトルが「デラックス」で終わるソフト
- タイトルに「カービィ」が含まれているソフト
を探しました。
結果がこちら
うまく取れたようです。
Containsですがよく使うList.Contains()の方は完全一致だったような・・・?
LINQの場合は部分一致になるようです。
候補値検索
特定の候補に一致するものを検索します。
これは先程も出たContains()を使います。
using System; using System.Linq; namespace Test.LINQ { class SandBox { public static void Main(string[] args) { var sfcSoftTable = new SfcSoftTable(); var softTitles = sfcSoftTable.SoftTable.Where(val => new int[] { 7500, 9500 }.Contains(val.Price)) .OrderBy(val => val.Price) .Select(val => val.Title + " 価格:" + val.Price); foreach (var title in softTitles) { Console.WriteLine(title); } } } }
7500円か9500円のソフトを探してみました。
うまく検索できました。
範囲検索
特定の範囲に一致するものを検索します。
これにはメソッドはなく、演算子を使って操作します。
using System; using System.Linq; namespace Test.LINQ { class SandBox { public static void Main(string[] args) { var sfcSoftTable = new SfcSoftTable(); var softTitles = sfcSoftTable.SoftTable.Where(val => 11800 <= val.Price && val.Price <= 12000) .OrderBy(val => val.Price) .Select(val => val.Title + " 価格:" + val.Price); foreach (var title in softTitles) { Console.WriteLine(title); } } } }
11800円~12000円のソフトを探してみました。
結構ありましたね。
(雑感ですが、昔のゲームソフトは結構高価に感じますね。
しかし技術も作るコストも上がった今、こんくらいかそれ以上で売らないと
採算取れないんじゃないかと思うことがちょくちょくあります。)
単一の要素を取得する
単一の要素を検索するにはSingleメソッドを使います。
クロノ・トリガーを探してみました。
using System; using System.Linq; namespace Test.LINQ { class SandBox { public static void Main(string[] args) { var sfcSoftTable = new SfcSoftTable(); var soft = sfcSoftTable.SoftTable.Single(val => val.Title == "クロノ・トリガー"); Console.WriteLine(soft.Title + " 価格:" + soft.Price); } } }
Singleメソッドを使う時の注意として、
「複数合致するものがある」または「条件に合致するものがない」場合、
InvaildOperationException例外が発生します。
「絶対に結果を1つだけ取得できる」状況で使うべきらしいです。
特定のプロパティを取り出して加工(Selectメソッド)
Selectメソッドでは範囲変数からプロパティを取り出し、
加工することができます。
ジーコサッカーを見つけて名前と価格を変えてみました。
using System; using System.Linq; namespace Test.LINQ { class SandBox { public static void Main(string[] args) { var sfcSoftTable = new SfcSoftTable(); var soft = sfcSoftTable.SoftTable.Where(val => val.Title == "ジーコ サッカー") .Select(val => new { Title = "非公式ソフト", Price = " 60,000円" }); foreach (var val in soft) { Console.WriteLine(val.Title + val.Price); } } } }
重複を除去する
Distinctメソッドを使うと取り出したデータから重複を消せます。
メーカー名を重複を消して表示させてみました。
using System; using System.Linq; namespace Test.LINQ { class SandBox { public static void Main(string[] args) { var sfcSoftTable = new SfcSoftTable(); var soft = sfcSoftTable.SoftTable.OrderBy(val => val.Maker) .Select(val => val.Maker) .Distinct(); foreach (var val in soft) { Console.WriteLine(val); } } } }
グループ化
GroupByメソッドを使うと特定の項目でグループ化することができます。
メーカーでグループ化し、チュンソフトまたはアトラスのソフトを
取り出してみました。
using System; using System.Linq; namespace Test.LINQ { class SandBox { public static void Main(string[] args) { var sfcSoftTable = new SfcSoftTable(); var soft = sfcSoftTable.SoftTable.GroupBy(m => m.Maker); foreach (var maker in soft) { if (maker.Key == "チュンソフト" || maker.Key == "アトラス") { Console.WriteLine($"[{maker.Key}]"); foreach (var t in maker) { Console.WriteLine(t.Title); } Console.WriteLine(); } } } } }
複数のキーでグループ化することも可能なようです。
メーカーと発売年でグループ化して
アトラスの発売年ごとのソフトを出してみました。
using System; using System.Linq; namespace Test.LINQ { class SandBox { public static void Main(string[] args) { var sfcSoftTable = new SfcSoftTable(); var soft = sfcSoftTable.SoftTable.GroupBy(m => new { Maker = m.Maker, Releae = m.ReleaseDate.Year }); foreach (var g in soft) { if (g.Key.Maker == "アトラス") { Console.WriteLine($"[{g.Key.Maker} - {g.Key.Releae}]"); foreach (var t in g) { Console.WriteLine(t.Title); } Console.WriteLine(); } } } } }
この他にグループ化したのを更に絞り込んだり
複数のデータの結合をすることができるようです。
今回LINQのメソッドを少し使ってみましたが
ちょっと難しいというかややこしく感じました。
いろいろ使ってみたりして慣れて行こうと思います。