2010-10-04 61 views
2

我想通過使用擴展來獲得運行總數。現在它正在工作。Linq彙總序列號

public static IEnumerable<TResult> Rollup<TSource, TKey, TResult>(
     this IEnumerable<TSource> source, 
     Func<TSource, TKey> keySelector, 
     TResult seed, 
     Func<TSource, TResult, TResult> projection) 
    { 
     if (!source.Any()) 
     { 
      yield break; 
     } 

     TSource[] ordered = source.OrderBy(keySelector).ToArray(); 
     TKey previous = keySelector(ordered[0]); 

     TResult nextSeed = seed; 
     foreach (TSource src in source) 
     { 
      TKey current = keySelector(src); 
      if (!current.Equals(previous)) 
      { 
       nextSeed = seed; 
      } 
      TResult projectedValue = projection(src, nextSeed); 
      nextSeed = projectedValue; 
      yield return projectedValue; 

      previous = current; 
     } 
    } 

public class Items { 
    public string Item { get; set; } 
    public int Qty { get; set; } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     List<Items> myList = new List<Items>(); 
     myList.Add(new Items { Item = "A", Qty = 3 }); 
     myList.Add(new Items { Item = "A", Qty = 12 }); 
     myList.Add(new Items { Item = "B", Qty = 4 }); 
     myList.Add(new Items { Item = "B", Qty = 5 }); 
     myList.Add(new Items { Item = "A", Qty = 6 }); 
     myList.Add(new Items { Item = "A", Qty = 8 }); 
     myList.Add(new Items { Item = "B", Qty = 20 }); 

     var total = myList.OrderBy(x => x.Item).Rollup(x => x.Item, 0, (s, y) => s.Qty + y); 
     foreach (var i in total) 
     { 
      Console.WriteLine(i); 
     } 

     Console.ReadLine();  

    } 
} 

Output : 
    3 
    15 
    21 
    29 
    4 
    9 
    29 

我想同時獲得排序的序列。像波紋管

Seq Running Total 
    1 3 
    2 15 
    3 21 
    4 29 
    1 4 
    2 9 
    3 29 

任何人有一個很好的解決方案,以恢復在使用上面的LINQ擴展(彙總)在Sametime的順序和運行總計?

回答

3

這應該工作:

public class OrderSumPair<TResult> 
{ 
    public int Order { get; set;} 
    public TResult Value { get; set; } 
} 

public static IEnumerable<OrderSumPair<TResult>> Rollup<TSource, TKey, TResult>(
    this IEnumerable<TSource> source, 
    Func<TSource, TKey> keySelector, 
    TResult seed, 
    Func<TSource, TResult, TResult> projection) 
    { 
     if (!source.Any()) 
     { 
      yield break; 
     } 

     TSource[] ordered = source.OrderBy(keySelector).ToArray(); 
     TKey previous = keySelector(ordered[0]); 
     int count = 1; 

     TResult nextSeed = seed; 
     foreach (TSource src in source) 
     { 
      TKey current = keySelector(src); 
      if (!current.Equals(previous)) 
      { 
       nextSeed = seed; 
       count = 1; 
      } 
      TResult projectedValue = projection(src, nextSeed); 
      nextSeed = projectedValue; 
      yield return new OrderSumPair<TResult> { Order = count, Value = projectedValue }; 

      previous = current; 
      count++; 
     } 
    } 

而且你寫循環:

foreach (var i in total) 
    { 
     Console.WriteLine(i.Order + " " + i.Value); 
    } 
+0

太好了!它現在有效。謝謝你欣快! – Michael 2010-10-04 09:28:05