LINQ to Object のイディオム その2 : 集計演算子, 要素演算子, 限定子
ちょっといない隙に PLINQ/TPL や Volta や International Pack とかw VS2008 が出たばっかりなのに、なんなんだろう(^^; 遠い未来の夢と思ってたライブラリが急に目の前にポンと出てきて、なんだか戸惑ってしまってます。で、どれで遊ぶか迷った末に決めかねて結局 LINQ to Object で地味に(?)遊んでみました。
LINQ to Object の変なコードばっかり載せてしまってるので、たまには実用的な例を一挙に。遅くなるだけ、ややこしいだけじゃない LINQ to Object の簡単で便利なコードサンプルです。このサンプルのあたりなら、誰もが今すぐに恩恵を受けられるハズ。
using System; using System.Collections.Generic; using System.Linq; static class Program { static void Main() { var dic = new Dictionary<String, int> { { "バナナ", 10 }, { "いちご", 398 }, { "りんご", 298 } }; Console.WriteLine( "Keys: " + String.Join( ", ", dic.Keys.ToArray() ) ); Console.WriteLine( "Values: " + String.Join( ", ", dic.Values.Select( n => n.ToString() ).ToArray() ) ); Console.WriteLine( "Reverse: " + String.Join( ", ", ( from n in dic.Values.Reverse() select n.ToString() ).ToArray() ) ); Console.WriteLine( "Sum: " + dic.Values.Sum() ); Console.WriteLine( "Sum2: " + dic.Sum( e => e.Value ) ); Console.WriteLine( "Count: " + dic.Count() ); Console.WriteLine( "Count (n < 300): " + dic.Count( e => e.Value < 300 ) ); Console.WriteLine( "Min: " + dic.Min( e => e.Value ) ); Console.WriteLine( "Max: " + dic.Values.Max() ); Console.WriteLine( "Average: " + dic.Average( e => e.Value ) ); Console.WriteLine( "Reverse (Aggregate): " + dic.Keys.Reverse().Aggregate( "", ( s, n ) => s + n.ToString() + ", " ) ); Console.WriteLine( "dic[ 2 ]: " + dic.ElementAt( 2 ) ); Console.WriteLine( "Contains いちご: " + dic.Keys.Contains( "いちご" ) ); Console.WriteLine( "Contains 柿: " + dic.Keys.Contains( "柿" ) ); Console.WriteLine( "All (10 <= n): " + dic.Values.All( n => 10 <= n ) ); Console.WriteLine( "All (n < 100): " + dic.Values.All( n => n < 100 ) ); Console.WriteLine( "Any (n < 5): " + dic.Any( e => e.Value < 5 ) ); Console.WriteLine( "Any (n < 100): " + dic.Values.Any( n => n < 100 ) ); Console.WriteLine( "SingleOrDefault (n < 100): " + dic.SingleOrDefault( e => e.Value < 100 ) ); Console.WriteLine( "SingleOrDefault (n == 5): " + dic.SingleOrDefault( e => e.Value == 5 ) ); Console.WriteLine( "First: " + dic.First() ); Console.WriteLine( "Last: " + dic.Last() ); Console.ReadKey(); } }
実行結果
Keys: バナナ, いちご, りんご Values: 10, 398, 298 Reverse: 298, 398, 10 Sum: 706 Sum2: 706 Count: 3 Count (n < 300): 2 Min: 10 Max: 398 Average: 235.333333333333 Reverse (Aggregate): りんご, いちご, バナナ, dic[ 2 ]: [りんご, 298] Contains いちご: True Contains 柿: False All (10 <= n): True All (n < 100): False Any (n < 5): False Any (n < 100): True SingleOrDefault (n < 100): [バナナ, 10] SingleOrDefault (n == 5): [, 0] First: [バナナ, 10] Last: [りんご, 298]
いろんな書き方ができることを示すために、わざといろいろな書き方をしました。C#2.0 では、Array と List
参考: .NET 標準クエリ演算子
(追記)辞書のエントリ順に依存したコードは書かないようにご注意を。あくまでもサンプルですので。念のため。