LINQ to Objects by Example

    It would seem that the .NET Framework 3.5 and revolutionary LINQ in particular appeared among developers for a long time, but not all my colleagues still clearly understand what it is and what it is “eaten” with. Therefore, I decided to write a kind of introductory article for C # programmers in order to show with illustrative examples how LINQ saves time on routine things, such as sorting, aggregation, search, etc.

    First, let's decide what we will talk about LINQ to Objects. LINQ to SQL, XML, Entities, etc. This article is not covered, although I’m sure that most of the above examples will work there. In addition, starting with Silverlight 2.0, LINQ to Objects is also available there.

    LINQ to Objects is connected to the project by the assembly System.Core.dll + System.Linq namespace, implemented as a set of additional methods for any classes compatible with the IEnumerable interface. IEnumerable- This is a strongly typed version of amorphous IEnumerable, which appeared in the .NET Framework 1.0. IEnumerable Interface implemented in standard classes such as typed collectionslists ListsUnique HashSet ListsDictionary Dictionariesetc.

    To convert IEnumerable (e.g. ancient ArrayList) to IEnumerableThere are two possibilities:

    Cast - Converts any enumeration into a strongly typed version, using strict type conversion.

    object[] values = new object[] {"1", "2", "3", "AAA", 5};
    IEnumerable strings = values.Cast(); // завалится c исключением на последнем элементе, поскольку он не string

    Analog Cast in SQL-like LINQ syntax, it looks like this:

    IEnumerable strings = from string x in values select x;

    Oftype- converts any enumeration into a strongly typed version, using a weak type conversion, i.e. skipping elements that are not type T.

    object[] values = new object[] {"1", "2", "3", "AAA", 5};
    IEnumerable strings = values.OfType(); // последний элемент будет пропущен, поскольку он не string

    Where - filtering by the specified criteria.

    object[] values = new object[] { "1", "2", "3", "AAA", 5, "ABB" };
    IEnumerable strings = values.OfType().Where(i => i.StartsWith(“A”)); // извлекаем все строки, которые начинаются на A

    Firstand last- extract the first and last element of the enumeration. They fail with the exception if the recount does not contain elements.

    var values = new[] {"1", "AAA", "2", "3", "ABB"};
    IEnumerable strings = values.Where(i => i.StartsWith(“A”));
    string AAA = strings.First();
    string ABB = strings.Last();

    FirstOrDefaultand LastOrDefault- extract the first and last element of the enumeration. They work even if the enumeration does not contain elements, in this case they return default (T), which corresponds to null for reference types, 0 for numeric types, empty structures for structures.

    Fist, of Last, FirstOrDefault, LastOrDefault have an additional overloaded call option that accepts the lambda criterion function for filtering.

    var values = new[] { "1", "2", "3", "AAA", "ABB" };
    string AAA = values.FirstOrDefault(i => i.StartsWith("A"));

    In order to find out if there are elements that satisfy some condition, you can use the Any method.:

    var values = new[] { "1", "2", "3", "AAA", "ABB" };
    bool hasAAA = values.Any(i => i.StartsWith(“A”)); // true

    The same method can be used to check the enumeration for the presence of elements:

    var values = new[] { "1", "2", "3", "AAA", "ABB" };
    bool hasItems = values.Any(); // true

    To find out if all elements satisfy a certain condition, you can use the All method:

    var values = new[] { "1", "2", "3", "AAA", "ABB" };
    bool hasAAA = values.All(i => i.StartsWith("A")); // false

    You can calculate the number of elements that satisfy a certain criterion as follows:

    var values = new[] { "1", "2", "3", "AAA", "ABB" };
    int countAAA = values.Count(i => i.StartsWith("A")); // 2

    The condition can be omitted, then all elements will be counted:

    int countAll = values.Count(); // 5, понятно, что в данном случае это не самый оптимальный вариант узнать размер массива :)

    It’s very convenient to sort items using OrderBy.and OrderByDescending:

    var values = new[] { "1", "2", "3", "AAA", "ABB" };
    IEnumerable strings = values.OrderBy(i => i.Length);

    You can sort by several criteria as follows:

    var values = new[] { "1", "2", "3", "AAA", "ABB", "5", "6" };
    IEnumerable strings = values.OrderBy(i => i.Length).ThenBy(i => i);

    Same thing, but in SQL-like syntax:

    IEnumerable strings = from s in values order by s.Lenght, s select s;

    You can remove duplicates from the enumeration using the Distinct method.:

    var values = new[] { "1", "1", "2", "2", "3", "3", "3" };
    IEnumerable strings = values.Distinct(); // "1", "2", "3"

    One variation of this method accepts Comparer, i.e. for example, you can delete duplicate lines without checking for case:

    var values = new[] { "A", "B", "b", "C", "C", "c", "C" };
    IEnumerable strings = values.Distinct(StringComparer.OrdinalIgnoreCase); // "A", "B", "C"

    Expand the listing "to the forest before":

    var values = new[] { "A", "B", "C", "C" };
    IEnumerable strings = values.Reverse(); // "C", "C", "B", "A"

    Here are some quick examples of using LINQ to Objects. I hope the examples are eloquent enough to arouse your interest in further exploring and using LINQ to Objects ...

    (to be continued)

    Also popular now: