Mr. Toast
Mr. Toast

Reputation: 951

C# LINQ filtering lists

It's my first time using LINQ and I don't really get it yet.

I tried to understand it via an example but I need some help.

I created a class "Person":

class Person
{
    private string name { get; set; }
    private int age { get; set; }
    private bool parent { get; set; }
    private bool child { get; set; }

    public Person(string name, int age, bool parent, bool child)
    {
        this.name = name;
        this.age = age;
        this.parent = parent;
        this.child = child;
    }
}

I created a list of "people":

people.Add(new Person("Joel", 12, false, true));
        people.Add(new Person("jana", 22, false, false));
        people.Add(new Person("Stefan", 45, true, false));
        people.Add(new Person("Kurt", 25, false, false));
        people.Add(new Person("Sebastian", 65, true, false));
        people.Add(new Person("George", 14, false, true));
        people.Add(new Person("Noel", 50, true, false));

Now I would like to get out every person which is set as a parent. But I'm stuck here:

var parents = people.Where()

Upvotes: 4

Views: 10853

Answers (3)

Élie
Élie

Reputation: 1335

var peopleWithParents = people.Where(x => x.parent == true).ToList();

Although it may take a little while to get your head around, the syntax is pretty simple, and becomes really comfortable to use. Keep in mind that 'where' acts as a filter, and 'select' acts as a projection. Remember that you will need the properties to be publicly visible. You can keep the setters private if you like. You could even introduce a method to check that the parent exists, and call it in the lambda.

Let's say hypothetically that your person class was more complex.

class Person
{
    public string name { get; private set; }
    public int age { get; private set; }
    public Person parent { get; private set; }
    public bool child { get; private set; }

    public bool HasParent()
    {
        return parent != null;
    }

    public Person(string name, int age, Person parent, bool child)
    {
        this.name = name;
        this.age = age;
        this.parent = parent;
        this.child = child;
    }
}

You could do something like this to get a list of person objects representing all the parents:

var parents = people.Where(x => x.parent != null).Select(x => x.parent).ToList();

or

var parents = people.Where(x => x.HasParent()).Select(x => x.parent).ToList();

You also don't need to use 'x', and this letter is only in scope within each clause; could even order these parents by age:

var parents = people.Where(y => y.HasParent()).Select(z => z.parent).OrderBy(x => x.age).ToList();

Maybe you would like to get the oldest parent from the above collection:

var oldestParent = parents.OrderByDescending(x => x.age).FirstOrDefault();

if (oldestParent != null)
{
    Console.WriteLine($"{oldestParent.name} is the oldest, at {oldestParent.age}");
}

You can combine multiple checks in your query:

var parentsOfPeopleWithChildren = people.Where(x => x.parent != null && x.child).Select(x => x.parent).ToList();

Also recall that in C# you generally Capitalise the first letter of properties. Eg:

public bool Child { get; private set; }

Upvotes: 4

fubo
fubo

Reputation: 45947

The linq statement should be

var parents = people.Where(x => x.parent);

and change private bool parent { get; set; } to public bool parent { get; set; }

Upvotes: 9

Ian
Ian

Reputation: 30813

The LINQ is quite straight-forward:

var query = people.Where(x => x.parent);

However, your parent may not be accessible due to its access modifier.

If you don't want it to be changed from outside once declared (and that's likely the reason why you declare the properties by the constructor's parameters). I recommend you to use public { get; private set; }

class Person
{
    public string name { get; private set; }
    public int age { get; private set; }
    public bool parent { get; private set; }
    public bool child { get; private set; }

    public Person(string name, int age, bool parent, bool child)
    {
        this.name = name;
        this.age = age;
        this.parent = parent;
        this.child = child;
    }
}

Upvotes: 1

Related Questions