注意,上述兩種方法都假設輸入資料已排序。若非,需先對輸入資料排序。
若使用 LINQ,寫法更簡潔:
IEnumerable<Tuple<int, int, double>> Linq(IEnumerable<Tuple<int, double>> tuples)
{
var result = new List<Tuple<int, int, double>>();
var q = from k in tuples group k by k.Item1;
foreach (var g in q) result.Add(new Tuple<int, int, double>(g.Key, g.Count(), g.Average(v => v.Item2)));
return result;
}
但需注意 LINQ 方法無論執行時間或記憶體佔用都較大。
static void Main(string[] args)
{
try { new Program().Run(Console.Out, int.Parse(args[0])); }
catch (Exception ex) { Console.WriteLine(ex); }
}
void Run(TextWriter writer, int n)
{
var tuples = GetTuples(n * 1024 * 1024);
Write("ForEach", writer, ForEach(tuples));
Write("Iterate", writer, Iterate(tuples));
Write("Linq", writer, Linq(tuples));
}
void Write(string title, TextWriter writer, IEnumerable<Tuple<int, int, double>> tuples)
{
writer.WriteLine("==========> " + title + " <============");
writer.WriteLine("Key ------Count Average----------");
var count = 0; var sum = 0.0;
foreach (var t in tuples)
{
writer.WriteLine(" {0,3} {1,11:N0} {2}", t.Item1, t.Item2, t.Item3);
count += t.Item2; sum += t.Item2 * t.Item3;
}
writer.WriteLine("--- ----------- -----------------");
writer.WriteLine(" {0,3} {1,11:N0} {2}", tuples.Count(), count, sum / count);
writer.WriteLine();
}