はじめに
LINQのMaxやMinを使うこと最大値や最小値を取得する事が可能ですが、
//てきとうなリスト var list = new List<int>() {1, 2, 5, 125, -52, 58, -4, 8, 100}; //最大値と最小値を取得しログ表示 Debug.Log($"Max : {list.Max()}, Min : {list.Min()}");
最大値もしくは最小値を持つ要素の取得は出来ません。
//てきとうなディクショナリ var dict = new Dictionary<string, int>() { {"なまえ", 0}, {"サンプル", -10}, {"文字列", 58}, {"Key", 350}, {"てすと", 11}, {"すとりんぐ", -5} }; //最大値を持つ要素と最小値を持つ要素を取得したかった(エラーが出る) Debug.Log($"Max : {dict.Max()}, Min : {dict.Min()}");
ArgumentException: At least one object must implement IComparable.
System.Collections.Comparer.Compare (System.Object a, System.Object b)
という事で今回は最大値または最小値を持つ要素を取得する
LINQの拡張メソッド を作ろうという感じの記事です。
Debug.Log($"Max : {dict.MaxElement(pair => pair.Value).Key}, Min : {dict.MinElement(pair => pair.Value).Key}");
なお、Unity上で動かしているので、ログの表示にDebug.Logを使っています。
LINQExtension
さっそくですが最大値まは最小値を持つ要素を取得するLINQの拡張メソッド
を実装した拡張クラスLINQExtensionは以下の通りです。
なお、LINQの拡張メソッドを作るにはIEnumerableを使って拡張する感じになります。
using System; using System.Collections.Generic; using System.Linq; /// <summary> /// LINQの拡張クラス /// </summary> public static class LINQExtension { //================================================================================= //最大値、最小を持つ要素の取得 //================================================================================= /// <summary> /// 最大値を持つ要素の取得 /// </summary> public static T MaxElement<T>(this IEnumerable<T> source, Func<T, float> selector) { return source.OrderByDescending(selector).FirstOrDefault(); } /// <summary> /// 最大値を持つ要素の取得 /// </summary> public static T MinElement<T>(this IEnumerable<T> source, Func<T, float> selector) { return source.OrderBy(selector).FirstOrDefault(); } }
実装内容としてはシンプルで、
降順または昇順にソートして最初の一つ(なければデフォルト値)を取得するという物。
使い方としては引数のselectorで大きさを比較するための値を渡す感じです。
//てきとうなディクショナリ var dict = new Dictionary<string, int>() { {"なまえ", 0}, {"サンプル", -10}, {"文字列", 58}, {"Key", 350}, {"てすと", 11}, {"すとりんぐ", -5} }; //Valueの最大値を持つ要素を取得し、ログで表示 KeyValuePair<string, int> maxPair = dict.MaxElement(pair => pair.Value); Debug.Log($"最大値を持つ要素 : {maxPair.Key}, {maxPair.Value}");