views:

21

answers:

2

Hi, is it possible to define a LINQ statement for the following problems WITHOUT using a foreach loop?

public class GroupObject
{
    public String name;
    public List<String> letters;

    public void test()
    {
        List<GroupObject> myGroups = new List<GroupObject> {
            new GroupObject {
                name="test1",
                letters=new List<String>{"x","y","z"}
            },
            new GroupObject {
                name="test2",
                letters=new List<String>{"l","m","n"}
            },
            new GroupObject {
                name="test3",
                letters=new List<String>{"m","x","z"}
            }
        };

        // LINQ problem 1: how to get a list of all 9 letters
        // List<string> allLetters = (from ...).ToList();

        // LINQ problem 2: how to get a list of all 6 DISTINCT letters
        // List<string> allDistictLetters = (from ...).ToList();
    }
}

While writing this question, I found a solution to the problems. I will still post (and answer) the question, since this one was a real bugger for me. And I did not find a suitable existing question here.

Ciao, Juve

+2  A: 

I believe this problem can be solved by SelectMany and Distinct!

var allLetters = myGroups.SelectMany(go => go.letters);
var allUniqueLetters = allLetters.Distinct();

The second variable name is misleading tho. It will return, among other letters, one instance of "m", which was not unique in the original collection ;)

David Hedlund
Wow, you were really fast! I'll try that.
Juve
Works perfect! And it's much shorter than my solution. Even if it might be more cryptic for people who do not understand lambda.Thx very much!
Juve
@Juve: you're welcome. i find that `from ...` selectors quickly become *extremely* cryptic when they get a little more complicated than this. and if this prompts the reader to go ahead and learn how lambda works in C#, you will have helped them tremendously ;)
David Hedlund
A: 

As stated above, I found the answer myself:

List<string> allLetters = (from g in myGroups from l in g.letters select l).ToList();
List<string> allDistinctLetters = allLetters.Distinct().ToList();

I hope this helpful for somebody.

Ciao, Juve

Juve