使用LINQ将增量属性添加到IEnumerable组

时间:2009-08-14 21:35:39

标签: linq

为简化方案,假设我们有一个包含FirstName和LastName属性的人员列表。

我们的数据如下:

Bob    Smith
Jane   Smith
Todd   Grover
Larry  Lewis
Jill   Lewis
Frank  Lewis

第一步是添加一个Integer属性,该属性为每个项目增加:

Bob    Smith  1
Jane   Smith  2
Todd   Grover 3
Larry  Lewis  4
Jill   Lewis  5
Frank  Lewis  6

理想情况下,我想为每个新组重置计数器以实现此目的:

Bob    Smith  1
Jane   Smith  2
Todd   Grover 1
Larry  Lewis  1
Jill   Lewis  2
Frank  Lewis  3

也许LINQ不合适。看起来LINQ应该能够优雅地做到这一点。

3 个答案:

答案 0 :(得分:5)

如果您只想要一个随每个项目递增的计数器:

var query = people
    .Select((x, i) => new { x.FirstName, x.LastName, Index = i + 1 });

或者,如果您要重置每个组的计数器,请按LastName分组:

var query = people
    .GroupBy(x => x.LastName)
    .Select
    (
        x => x.Select((y, i) => new { y.FirstName, y.LastName, Index = i + 1 })
    )
    .SelectMany(x => x);

并快速显示查询结果:

foreach (var item in query)
{
    Console.WriteLine(item.FirstName + "\t" + item.LastName + "\t" + item.Index);
}

答案 1 :(得分:2)

您可以使用Select方法的第二个重载,该方法包含传递给lambda表达式的索引参数,例如:

var people = new [] {
  new { FirstName = "Bob",   LastName = "Smith"},
  new { FirstName = "Jane",  LastName = "Smith"},
  new { FirstName = "Todd",  LastName = "Grover"},
  new { FirstName = "Larry", LastName = "Lewis"},
  new { FirstName = "Jill",  LastName = "Lewis"},
  new { FirstName = "Frank", LastName = "Lewis"},
}.ToList();

people.Select((p, index) => new {
                                  FirstName = p.FirstName,
                                  LastName = p.LastName,
                                  Index = index
                                }
             );

结果:

select-index

答案 2 :(得分:1)

假设记录类型上已存在整数属性,并且该集合已经排序,那么您可以滥用Aggregate(即左侧),类似这样的

collection.Aggregate( (old, next) => { if (namesDiffer(old, next)) next.Index = 1 else next.Index = old.Index +1; return next;}, aRecordWithEmptyName);

编辑 - 固定回报值;手指一直在自动驾驶仪上。