static IEnumerable <IEnumerable <T> > Transpose <T>(this IEnumerable <IEnumerable <T> > matrix) { return(matrix.Count() == 0 ? ZipEnumerable.Return(Enumerable.Empty <T>()) : from xs in matrix.First() join xss in Transpose(matrix.Skip(1)) on 1 equals 1 select Enumerable.Concat(new[] { xs }, xss)); }
static void Main(string[] args) { var prices = new[] { new[] { 10.0, 4.0, 13.0, 20.0 }, new[] { 12.0, 3.0, 11.0, 25.0 }, new[] { 9.0, 1.0, 16.0, 24.0 }, }; // Calculating average stock prices using idioms (directly) var res1 = ZipEnumerable.Return(0.0); foreach (var day in prices) { res1 = res1.Merge(day).Select(tup => tup.Item1 + tup.Item2); } var avg1 = res1.Select(sum => sum / prices.Count()); // Calculating average stock prices using idioms (LINQ) var res = ZipEnumerable.Return(0.0); foreach (var day in prices) { res = from sum in res join price in day on 1 equals 1 select sum + price; } var avg = from sum in res select sum / prices.Count(); foreach (var price in avg) { Console.Write("{0}, ", price); } // Matrix transposition example var matrix = new[] { new[] { 1, 2, 3 }, new[] { 10, 20, 30 }, new[] { 100, 200, 300 } }; var transposed = matrix.Transpose(); foreach (var a in transposed) { foreach (var b in a) { Console.Write("{0}, ", b); } Console.WriteLine(); } }
// Two versions of the Transpose operation based on // ZipList idiom using IEnumerable<T>. One version is written // directly and the other one uses LINQ syntax with 'join' #region Transpose from the blog post static IEnumerable <IEnumerable <T> > Transpose2 <T>(this IEnumerable <IEnumerable <T> > matrix) { if (matrix.Count() == 0) { return(ZipEnumerable.Return(Enumerable.Empty <T>())); } else { return (ZipEnumerable. Merge(matrix.First(), Transpose(matrix.Skip(1))). Select(tuple => Enumerable.Concat(new[] { tuple.Item1 }, tuple.Item2))); } }