20

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).

Fabian Steeg
  • 44,988
  • 7
  • 85
  • 112
Joe Albahari
  • 30,118
  • 7
  • 80
  • 91

9 Answers9

8

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
  • 70,676
  • 20
  • 104
  • 133
  • 3
    `somelist.Where(a => a != null)` is a bit less efficient than `somelist.OfType()` – Gabe Sep 26 '10 at 05:02
4

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
  • 9,976
  • 1
  • 39
  • 82
3

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
  • 33,874
  • 33
  • 95
  • 118
  • Which reference do you need for the 1st example? I've tried it in LinqPad but it is missing an assembly reference. – Matt Jun 11 '13 at 07:30
2

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
  • 5,538
  • 9
  • 44
  • 63
2

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]);
Igal Tabachnik
  • 31,174
  • 15
  • 92
  • 157
1

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
  • 6,106
  • 7
  • 43
  • 56
0

My favorite is the following Linq example for dynamically sorting a SQL table from the Northwind database:

void Main()
{

// Demonstrates dynamic ordering

var SortExpression = "Total"; // choose ProductName or Total
var sortAscending = true; // choose true for ascending, false for descending

// the query to sort
var data = (from pd in Products
                    join od in OrderDetails on pd.ProductID equals od.ProductID into DetailsByProduct
                    select new { ProductName = pd.ProductName, Total = DetailsByProduct.Count()}).ToList();

// the data source you can use for data binding                     
var ds= (sortAscending) 
    ? data.OrderBy(x => x.GetType().GetProperty(SortExpression).GetValue(x, null))
    : data.OrderByDescending(x => x.GetType().GetProperty(SortExpression).GetValue(x, null));

ds.Dump();
}

It allows you to dynamically sort by simply specifying a field in the variable SortExpression and a sort order in the variable sortAscending.

By using .Take(x) and .Skip(y) you can as well implement paging easily.

Matt
  • 25,467
  • 18
  • 120
  • 187
0

I like to use LINQ on text when I'm porting code:

For example:

String.Join("\n", @"some VB6 code
    that I could refactor automatically
    if FindAndReplace were a bit more powerfully
    And I don't want to refactor by hand".Split('\n').Trim().Select(line =>
    {
        if(line.Contains("FindAndReplace") && !line.StartsWith("//"))
        {
            return line.Split(" ").Last();
        }
        else
        {
            return String.Join("_", line.Split(" ").Take(3));
        }
    });

You get the idea. Linq lets me apply the full power of C# to text transformation. Typically I use it when I have code in one language that I want to extract and manipulate in a complex manner, I throw the text alone in LinqPad and do a "find-replace" on quotation marks, replacing them with double quotation marks, then I surround it by @"..." and get to work. I can usually do massive code transformations in 30 seconds or so.

Chris Pfohl
  • 18,220
  • 9
  • 68
  • 111
0

Got me started and its awesome!

var myList = from list in myObjectList select list
Pure.Krome
  • 84,693
  • 113
  • 396
  • 647
Filip Ekberg
  • 36,033
  • 20
  • 126
  • 183
  • Sorry, I am not getting the idea. What is so special about this example? – Matt Oct 29 '15 at 14:18
  • @Matt 7 years ago that was pretty neat. – Filip Ekberg Jan 07 '16 at 04:43
  • @Matt because it was a really simple, yet powerful, way to quickly iterate over of list. From there, it's easy to add where clauses, etc to _really_ get some awesome results. Code would be clean and simple to read. – Pure.Krome Jan 07 '16 at 06:08
  • @Pure.Krome/Filip Ekberg - I agree, however `var myList = myObjectList.AsQueryable();` would do the same but shorter. – Matt Jan 11 '16 at 10:06
  • @Matt, That's not LINQ though. – Filip Ekberg Jan 11 '16 at 22:34
  • Ok, it is not a query, but it has the same effect as the query you provided: it converts a list of objects into a queryable datatype. You can then use myList in subsequent Linq queries, e.g. `from x in myList where x.aNumericProp>5 select x`. And btw, `.AsQueryable()` only creates 3 lines of IL code (`ldloc.0`, `call System.Linq.Queryable.AsQueryable`, `stloc.2`) as you can see in LinqPad's IL tab. – Matt Jan 12 '16 at 08:29