tags:

views:

158

answers:

3

To simplify the scenario, let's say we have a list of People with FirstName and LastName properties.

Our data looks like this:

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

The first step would be to add an Integer property that gets incremented for each item:

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

Ideally, I'd like to reset the counter for every new group to achieve this:

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

Maybe LINQ isn't appropriate. It just seems like LINQ should be able to do this elegantly.

+1  A: 

Assuming there is an integer property already on the record type, and the collection is already sorted, then you can abuse Aggregate (i.e. left-fold), something like this

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

EDIT -- fixed return value; fingers had been on autopilot.

Steve Gilham
+2  A: 
CMS
+2  A: 

If you just want a counter that increments with each item:

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

Or if you want to reset the counter for each group, grouped by 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);

And to quickly display the query results:

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