Navigate / search

LINQ is not so bad

Increasingly, the projects begin to use LINQ and begin to see advantages. Not only, that in this way can write some code, and gain some clarity. Below are some examples, which slowly skim through the LINQ. For demonstration purposes, let’s create a class Person, which objects will be represented by a person.

class Person : IComparable
  {
    public Person(string name, string surname, int age, bool married)
    {
      this.Name = name;
      this.Surname = surname;
      this.Age = age;
      this.Married = married;
    }

    public Person()
    {}

    public string Name { get; set; }

    public string Surname { get; set; }

    public int Age { get; set; }

    public bool Married { get; set; }

    public int CompareTo(object obj)
    {
      Person otherPerson = obj as Person;
      if (otherPerson != null)
        return Surname.CompareTo(otherPerson.Surname) == 0 ? (Name.CompareTo(otherPerson.Name) == 0
           ? Age.CompareTo(otherPerson.Age)
           : Name.CompareTo(otherPerson.Name)) : Surname.CompareTo(otherPerson.Surname);
      else
        throw new ArgumentException("Object is not a Person");
    }

As you can see class has four properties:

  • first name,
  • last name,
  • age,
  • information, does anyone have a wife or husband.

Additionally, in the class are defined two constructors. One default, and the second is assigning values ​​to the previously mentioned properties. Class also implements the interface IComparable, but more on that later.

The first scenario, where I want to demonstrate the superiority LINQ the classical approach is the situation in which you should select the objects that meet certain criteria. For example, suppose, Select the objects that, which satisfy the following conditions:

  • people must have more than 20 years,
  • persons are married, or married.

Normally this problem is solved by building a loop, which passes through all the items and checks, whether an object meets the search criteria. In a situation, where the criteria are met the object is copied to the target list. This algorithm presents the following code:

List<Person> filtered = new List<Person>();
foreach (Person pearson in people)
{
  if (pearson.Age > 20 && pearson.Married)
  {
    filtered.Add(pearson);
  }
}

The same can be done theoretically by using a single line of code using LINQ:

var filtered2 = from currentPearson in people
        where currentPearson.Age > 20 && currentPearson.Married
        select currentPearson

It seems to me, that the solution with LINQ is much more readable and easier to maintain later.

Another example is a modification of the current. Let’s add to the example, we want to retrieve only the first two elements. In the classical approach, you can do it this way:

List<Person> filtered = new List<Person>();
for (int i = 0; i < people.Count && filtered.Count < 2; i++)
{
  if (people&#91;i&#93;.Age > 20 && people[i].Married)
  {
    filtered.Add(people[i]);
  }
}

In LINQ This code can be replaced as follows:

var filtered2 = people.Where(p => p.Age > 20 && p.Married).Take(2)

I can see again, that the solution LINQ is more simple and readable.

In my code, quite often there is also a need to download the first item from the collection. The classic way to check whether the collection is properly initialized, and it contains some elements. Only then can we get an interesting element.

Person person1;
if (people != null && people.Count > 0)
{
  person1 = people[0];
}

In LINQ This is a trivial task:

Person person2 = people.FirstOrDefault();

The last example is related to the sorting. Classically, to sort the collection must implement the interface in the facility IComparable and use a method Sort(). The implementation of this interface can be found at the beginning of the article in the place where the class presented Person. The solution is relatively simple, if you want to sort the list is always in the same way. But in a situation, when we want, that it can sort in different ways matter is already a bit complicated.

people.Sort();

The case looks much more optimistic in LINQ. Just one line, to achieve what gave us the implementation of interface IComparable:

var sortedPeople = people.OrderBy(u => u.Surname).ThenBy(u => u.Name).ThenBy(u => u.Age);

Additionally, if we want the next line we want to change the sort order that there is nothing, to do so in the way.

sortedPeople = people.OrderBy(u => u.Surname).ThenBy(u => u.Name).ThenByDescending(u => u.Age);

As well there are no obstacles, prior to sorting your results and choose only those elements, we are interested:

sortedPeople = people.Where(p => p.Age > 20 && p.Married).OrderBy(u => u.Surname)
.ThenBy(u => u.Name).ThenByDescending(u => u.Age);

Comments

avatar
aks
Reply

Cześć,
potrzebuję dopasować zapytanie w linq do wzorca regularnego mam coś takiego ale mi to nie działa…
Regex rgx = new Regex(pattern);
string passtru = db.Users.Where(s => s.login == log && s.password.rgx.IsMatch(pattern)).FirstOrDefault().name;

jakaś podpowiedź?

avatar
Michał Jankowski
Reply

Łap przykład:

var names = new string[] { “Michal”, “Adam”};

string pattern = “M*”;
Regex rgx = new Regex(pattern);

var nameOnM = names.Where(name => rgx.IsMatch(name)).FirstOrDefault();

avatar
Yelrty
Reply

Mimo że lubię LINQ, uważam że należy używać go z głową i rozumieć jak działa.
Ja w firmie znajduję np. takie kwiatki:

private int Get(IList lista)
{
var filteredItems = lista.Where(item => CanSomething(item));
var value = filteredItems.Count() > 0 ? filteredItems.First().Value : 0;
return paymentValue;
}

A można przecież napisać też czytelnie i wydajniej (bez LINQ) :
private int Get(IList lista)
{
for (var i = 0; i < lista.Count; i++)
{
if (CanSomething(lista[i]))
return lista[i].Value;
}
return 0;
}

Leave a comment

name*

email* (not published)

website

This site uses Akismet to reduce spam. Learn how your comment data is processed.

.