Marking position in a C# list

I have a list of strings which have been read in from a dictionary file (sorted into alphabetical order). I want to create an index of the last position of each starting letter, so if there were 1000 words beginning with A it would be recorded as position 999 (because arrays start from 0). 1000 words beginning with B would mean the end position of B is 1999 and so on. These position values will be stored in a int array.

The only way I can think to do this is loop through the whole list, and have lots of else if statements to look at the first letter of the word. Not the most elegant solution.

Does anyone know of a simple way to do this, rather than 26 if statements?

Edit: The purpose of this is to generate random words. If I wanted a word beginning with B I would generate a random number between 1000 and 1999 and get the word from that position in the list.

Jon Skeet
people
quotationmark

Well, you could create a dictionary using LINQ:

// Note: assumes no empty words
Dictionary<char, int> lastEntries = words
    .Select((index, value) => new { index, value })
    .GroupBy(pair => pair.value[0])
    .ToDictionary(g => g.Key, g => g.Max(p => p.index));

Or more usefully, keep the first and last indexes:

Dictionary<char, Tuple<int, int>> entryMinMax = words
    .Select((value, index) => new { value, index })
    .GroupBy(pair => pair.value[0])
    .ToDictionary(g => g.Key,
                  g => Tuple.Of(g.Min(p => p.index), g.Max(p => p.index));

Alternatively, if the point is to effectively group the words by first letter, just do that, using a lookup:

ILookup<char, string> lookup = words.ToLookup(word => word[0]);

Then you can use:

char first = 'B'; // Or whatever
Random rng = new Random(); // But don't create a new one each time...
var range = lookup[first];
var count = range.Count();
if (count == 0)
{
    // No words starting with that letter!
}
int index = random.Next(count);
var randomWord = range.ElementAt(index);

people

See more on this question at Stackoverflow