views:

431

answers:

7

With LINQ, a lot of programming problems can be solved more easily - and in fewer lines of code.

What are some the best real-world LINQ-to-Objects queries that you've written?

(Best = simplicity & elegance compared to the C# 2.0 / imperative approach).

A: 

Got me started and its awesome!

var myList = from list in myObjectList select list

Filip Ekberg
+5  A: 

Filter out null items in a list.

var nonnull = somelist.Where(a => a != null);

Create a dictionary where the key is the value of a property, and the value is the number of times that property appears in the list.

var countDictionary = somelist
    .GroupBy(a => a.SomeProperty)
    .ToDictionary(g => g.Key, g => g.Count());
Cameron MacFarland
`somelist.Where(a => a != null)` is a bit less efficient than `somelist.OfType<T>()`
Gabe
+2  A: 

LINQ is merely the addition of some functional programming concepts to C#/VB. Hence, yes, most things tend to get much easier. C# 2.0 actually had some of this -- see the List methods, for instance. (Although, anonymous method syntax in C# 2.0 was too verbose.)

Here's one little example:

static readonly string badChars = "!@#$%^&*()";
bool IsUserNameValid(string userName) {
  return userName.Intersect(badChars).Any();
}
MichaelGG
+1  A: 

If you have a list (i.e. List<Palette> palettes) that contains objects which contains another list (i.e. Palette.Colors) and want to flatten all those sub-lists into one:

List<Color> allColors = palettes.SelectMany(p => p.Colors);
Anthony Brien
+1  A: 

Example 1

Returns list with names of all available instances of SQL Server within the local network

private List<string> GetServerNames()
{
    return SqlDataSourceEnumerator.Instance.GetDataSources().Rows.
        Cast<DataRow>().
        Select
        (
            row => row["ServerName"].ToString() + 
                  (row["InstanceName"] != DBNull.Value ? "\\" + row["InstanceName"].ToString() : "") + 
                  (row["Version"] != DBNull.Value ? " (" + row["Version"].ToString().Substring(0, 3) + ")" : "")
        ).
        OrderBy(s => s).
        ToList();
}

Example 2

Generates not used name for new file

private string NewName(string newNamePrefix, List<string> existingFileNames)
{
    return newNamePrefix + 
        (existingFileNames.
            Select
            (
                n =>
                {
                    if (n.StartsWith(newNamePrefix))
                    {
                        int i;
                        if (int.TryParse(n.Replace(newNamePrefix, ""), out i))
                            return i;
                    }

                    return 0;
                }
            ).
            OrderBy(i => i).
            Last() + 1
        );
}
Alexander Prokofyev
+1  A: 

I have two nicely absurd but elegant examples that I love

public static IEnumerable<bool> Information(this byte x)
{
    return Enumerable.Range(0, 8).Select(i => ((x >> i) & 1) == 1);
}

public static IEnumerable<bool> Information(this IEnumerable<byte> xs)
{
    return xs.SelectMany(Information);
}

Albeit these are encapsulated as query operators so you can reuse them, e.g. for binary parsing

var n = bytes.Information().Skip(3).Take(16).ToInt();
Bent Rasmussen
I see - it's a ToBits() function. Nice.
Joe Albahari
Yes; I prefer the name Information as the smallest unit of information is a bit. It should haven been an extension property though but we don't have those yet.
Bent Rasmussen
+1  A: 

If you have a delimited Name=Value string, such as "ID=2;Name=James;Age=32;" and you want to turn this into a dictionary quickly, you can use:

var dict = value.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries)
    .Select(str => str.Split('='))
    .ToDictionary(pair => pair[0], pair => pair[1]);
hmemcpy