今回のテーマ
今回はLinqのGroupbyをした後に各グループから2番目に大きい(小さい)レコードを
取り出す方法を解説していきます。
意外と2番目や3番目の要素を取り出したい場面って多いですよね。
その度に検索しますが、意外と見つからないんですよね。
この記事では、Groupby後の各グループから2番目に大きいレコードを取り出すことを目標とします。
早速やっていきましょう!!
配列から2番目に大きい要素を取り出してみよう
まずはLinqを使用し、下記の配列から2番目に大きい値を出力してみます。
2番目に大きい5を出力することが出来れば良さそうですね。
int[] numbers = { 2, 5, 4, 6, 3, 1 };
最大値や最小値を導くには、MaxやMinを使用することで、取得することができますが、
2番目に大きなメソッドを取得するメソッドは用意されていません。
色々考えた所、下記のようにLinqメソッドを組み合わせることで、実現することが出来ました。
1 2 3 4 5 6 7 8 9 10 11 12 |
using System; using System.Linq; class Program { static void Main(string[] args) { int[] numbers = { 2, 5, 4, 6, 3, 1 }; var number = numbers.OrderByDescending(n => n).Skip(1).FirstOrDefault(); Console.WriteLine(number); } } |
出力結果
5
3つのメソッドを組み合わせて実現することが出来ました。各メソッドの処理は下記の通りです。
step
1OrderByDescending
配列の要素を降順に並べる。
6,5,4,3,2,1
step
2Skip
1つ目の要素を飛ばす。
5,4,3,2,1
step
3FirstOrDefault
1つ目の要素のみ取得する。
5
以上の流れで二つ目に大きい数を取得することが出来ましたね。
ソートを行って実現しているため、膨大な量の要素を持っている配列やリストで使う時は要注意です。
上記の処理をGroupBy後の各グループにも使ってみましょう。
ロボットリストのGroupBy後に各グループで2つ目に大きい要素を取り出してみよう。
それでは、下記のロボットクラスを用いて2番目に大きいレコードのみ出力してみましょう。
今回は色別のグループに分けて、各グループの2番目に強いロボット名を出力してみます。
step
1使用するロボットクラス
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
class Robot { string name, maker, color; int strength; public Robot(string _name,string _maker,string _color,int _strength) { name = _name; maker = _maker; color = _color; strength = _strength; } public string getName() { return name; } public string getMaker() { return maker; } public string getColor() { return color; } public int getstrength() { return strength; } } |
step
2ロボットリストに追加するレコード
1 2 3 4 5 6 7 8 9 10 |
List<Robot> robotlist = new List<Robot>(); robotlist.Add(new Robot("Rockman", "Mr Light", "Blue", 5)); robotlist.Add(new Robot("Quickman", "Mr Wily", "Red", 5)); robotlist.Add(new Robot("Airman", "Mr Wily", "Blue", 3)); robotlist.Add(new Robot("Rollchan", "Mr Light", "Pink", 1)); robotlist.Add(new Robot("Woodman", "Mr Wily", "Green", 3)); robotlist.Add(new Robot("Bubbleman", "Mr Wily", "Green", 4)); robotlist.Add(new Robot("Fireman", "Mr Wily", "Red", 3)); robotlist.Add(new Robot("Iceman", "Mr Wily", "Blue", 4)); robotlist.Add(new Robot("Heatman", "Mr Wily", "Red", 2)); |
step
3色別にグループ化
var colorrobots = robotlist.GroupBy(n => n.getColor());
step
4色別のグループ2番目に強いロボットのみ出力
グループ化したリストに対して、上記で使用したメソッドの組み合わせを使用しましょう!
各グループに2体以上のロボットが存在しない場合はnullが返されるので除外します。
1 2 3 4 5 6 7 8 9 |
foreach (var colorrobot in colorrobots) { var strength2robot = colorrobot.OrderByDescending(n => n.getstrength()).Skip(1).FirstOrDefault(); if (strength2robot != null) { Console.WriteLine(strength2robot.getName()); } Console.WriteLine("-------------"); } |
まとめ(全体のソースコード)
以上を纏めると、下記のようなコードになりました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
using System; using System.Collections.Generic; using System.Linq; class Program { static void Main(string[] args) { List<Robot> robotlist = new List<Robot>(); robotlist.Add(new Robot("Rockman", "Mr Light", "Blue", 5)); robotlist.Add(new Robot("Quickman", "Mr Wily", "Red", 5)); robotlist.Add(new Robot("Airman", "Mr Wily", "Blue", 3)); robotlist.Add(new Robot("Rollchan", "Mr Light", "Pink", 1)); robotlist.Add(new Robot("Woodman", "Mr Wily", "Green", 3)); robotlist.Add(new Robot("Bubbleman", "Mr Wily", "Green", 4)); robotlist.Add(new Robot("Fireman", "Mr Wily", "Red", 3)); robotlist.Add(new Robot("Iceman", "Mr Wily", "Blue", 4)); robotlist.Add(new Robot("Heatman", "Mr Wily", "Red", 2)); //色別にグループ化 var colorrobots = robotlist.GroupBy(n => n.getColor()); foreach (var colorrobot in colorrobots) { var strength2robot = colorrobot.OrderByDescending(n => n.getstrength()).Skip(1).FirstOrDefault(); if (strength2robot != null) { Console.WriteLine(strength2robot.getName()); } Console.WriteLine("-------------"); } } } |
出力結果
Iceman
-------------
Fireman
-------------
-------------
Woodman
-------------
色別で2番目に強いロボット名のみ表示されていますね。ピンクの場合は2体以上いないので、空白で出力されています。
因みにSkipの値を変更すれば、3番目、4番目も同様に取得することが出来るので、是非使ってみてくださいね。
今回使用したメソッドについて、下記の記事で詳しく解説しています。
-
参考【C# sharp Linq】Count、SequenceEqual、FirstOrDefault、LastOrDefaultメソッドを解説します。
ChatGPTのAPIを使わずに自動化することが可能です。 下記の本を読めば、ChatGPT4でも料金掛からずに自動化できます!KindleUnlimited会員であれば無料で読めます。 今回のテーマ ...
続きを見る
-
参考【C# sharp Linq】Take、Skip、TakeWhile、SkipWhileメソッドを解説します。
ChatGPTのAPIを使わずに自動化することが可能です。 下記の本を読めば、ChatGPT4でも料金掛からずに自動化できます!KindleUnlimited会員であれば無料で読めます。 今回のテーマ ...
続きを見る
-
参考【C# sharp Linq】Distinct、OrderBy、OrderByDescendingメソッドを解説します。
ChatGPTのAPIを使わずに自動化することが可能です。 下記の本を読めば、ChatGPT4でも料金掛からずに自動化できます!KindleUnlimited会員であれば無料で読めます。 今回のテーマ ...
続きを見る