按总金额分组项目

时间:2012-08-01 13:13:57

标签: c# .net linq group-by

假设我有这个号码列表:

List<int> nu = new List<int>();
nu.Add(2);
nu.Add(1);
nu.Add(3);
nu.Add(5);
nu.Add(2);
nu.Add(1);
nu.Add(1);
nu.Add(3);

保持列表项的顺序相同,是否可以将linq中的项目分组为6,这样结果将是这样的:

2,1,3 - 5 - 2,1,1 - 3

2 个答案:

答案 0 :(得分:6)

直接用LINQ解决这个问题会很麻烦,相反,你可以做一个扩展方法:

// Assumptions:
//  (1) All non-negative, or at least you don't mind them in your sum
//  (2) Items greater than the sum are returned by their lonesome
static IEnumerable<IEnumerable<int>> GroupBySum(this IEnumerable<int> source,
    int sum)
{
    var running = 0;
    var items = new List<int>();
    foreach (var x in source)
    {
        if (running + x > sum && items.Any())
        {
            yield return items;
            items = new List<int>();
            running = 0;
        }

        running += x;
        items.Add(x);
    }

    if (items.Any()) yield return items;
}

答案 1 :(得分:4)

你可以使用Aggregate。

(旁注:使用LinqPad测试/编写这些类型的查询,使其变得简单)

给出了这些结果:

results

像这样:

class Less7Holder
{
   public List<int> g = new List<int>();
   public int mySum = 0;
}

void Main()
{
    List<int> nu = new List<int>();
    nu.Add(2);
    nu.Add(1);
    nu.Add(3);
    nu.Add(5);
    nu.Add(2);
    nu.Add(1);
    nu.Add(1);
    nu.Add(3);

    var result  = nu .Aggregate(
       new LinkedList<Less7Holder>(),
       (holder,inItem) => 
       {
          if ((holder.Last == null) || (holder.Last.Value.mySum + inItem >= 7))
          {
            Less7Holder t = new Less7Holder();
            t.g.Add(inItem);
            t.mySum = inItem;
            holder.AddLast(t);
          }
          else
          {
            holder.Last.Value.g.Add(inItem);
            holder.Last.Value.mySum += inItem;
          }
          return holder;
       },
       (holder) => { return holder.Select((h) => h.g );} );

   result.Dump();

}