tags:

views:

201

answers:

3

I have a list of objects. Each object contains a property called 'DisplayName'.

I want to create another list of string objects, where each string represents the first letter or character (could be a number) in the DisplayName property for all objects in the initial list, and I want the list to be distinct.

So, for example, if my list contained the following three objects:

(1) DisplayName = 'Anthony' (2) DisplayName = 'Dennis' (3) DisplayName = 'John'

I would want to create another list containing the following three strings:

(1) 'A' (2) 'D' (3) 'J'

Any idea how to do this with minimal coding using lambda expressions or linq?

+2  A: 

Like this:

list.Select(o => o.DisplayName[0].ToString())
    .Where(s => Char.IsLetter(s, 0))
    .Distinct().ToList();

Edited

SLaks
Thanks. Is it possible to filter out results that have a non-alpha character? I know that my original post stated that it was ok if the first character was numeric or a symbol - but - I am curious if I can filter these out of the results returned?
Chris
Use a Where call with one of the static methods in Char.
SLaks
A: 

or in query notation:

var stringList = (from a in objectList 
                      select a.DisplayName.Substring(0,1)).Distinct();
Zenon
Query comprehension syntax is overrated.
SLaks
+1  A: 
List<myObject> mylist = new List<myObject>();
//populate list
List<string> myStringList = myList
    .Select(x => x.DisplayName.Substring(0,1))
    .Distinct()
    .OrderBy(y => y);

In the above code, Select (with it's lambda) returns only the first character from the display name of object x. This creates an IEnumerable of type string, which is then passed to Distinct(). This makes sure you have only unique items in the list. Finally, OrderBy makes sure your items are sorted alphabetically.

Note, if each of the objects in the list are of different types, you won't be able to just call x.DisplayName. In that case, I would create an interface, possibly called IDisplayName, which implements DisplayName. Then you should be able to use x => ((IDisplayName)x).DisplayName.Substring(0,1) within your lambda.

Ben McCormack