Reputation: 621
In the example below, I have a list of people who have many pets. Is there a way to return the pets with an age that is > than 5
, but exclude the other pets that person owns where the age is NOT > 5 years
Example: If a person has 2 pets one is 6 years, the other is 2 years, then return that person and the 6-year-old pet, and EXCLUDE the 2-year-old pet from the list.
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}
class Person
{
public string LastName { get; set; }
public Pet[] Pets { get; set; }
}
public static void AllEx2()
{
List<Person> people = new List<Person>
{ new Person { LastName = "Haas",
Pets = new Pet[] { new Pet { Name="Barley", Age=10 },
new Pet { Name="Boots", Age=14 },
new Pet { Name="Whiskers", Age=6 }}},
new Person { LastName = "Fakhouri",
Pets = new Pet[] { new Pet { Name = "Snowball", Age = 1}}},
new Person { LastName = "Antebi",
Pets = new Pet[] { new Pet { Name = "Belle", Age = 8} }},
new Person { LastName = "Philips",
Pets = new Pet[] { new Pet { Name = "Sweetie", Age = 2},
new Pet { Name = "Rover", Age = 13}} }
};
people.ForEach(person=>
{
person.Pets.Where(pet => pet.Age > 5);
});
}
Upvotes: 0
Views: 126
Reputation: 713
I think this might solve your problem. Try something like this
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}
class Person
{
public string LastName { get; set; }
public Pet[] Pets { get; set; }
}
public static void AllEx2()
{
List<Person> people = new List<Person>
{ new Person { LastName = "Haas",
Pets = new Pet[] { new Pet { Name="Barley", Age=10 },
new Pet { Name="Boots", Age=14 },
new Pet { Name="Whiskers", Age=6 }}},
new Person { LastName = "Fakhouri",
Pets = new Pet[] { new Pet { Name = "Snowball", Age = 1}}},
new Person { LastName = "Antebi",
Pets = new Pet[] { new Pet { Name = "Belle", Age = 8} }},
new Person { LastName = "Philips",
Pets = new Pet[] { new Pet { Name = "Sweetie", Age = 2},
new Pet { Name = "Rover", Age = 13}} }
};
people.ForEach(person=>
{
// create an array with the result and reassign it to the respt array
var pets = person.Pets.Where(pet => pet.Age > 5).ToArray();
person.Pets = pets;
});
}
This SO Question may be the reason. Please go through it. You will get an idea why this doesn't filter the values in your loop
Upvotes: 1
Reputation: 136074
If you create a function do do the predicate
part of a Where
linq query you can resuse this for both filtering the Person
objects and also getting the required list of pets
Func<Pet,bool> petsOver5 = (Pet p) => p.Age > 5;
and then
var peopleWithPetsOver5 = people.Where(p => p.Pets.Any(petsOver5));
foreach(var person in peopleWithPetsOver5)
{
Console.WriteLine($"Here are {person.LastName}'s pets over 5:");
foreach(var pet in person.Pets.Where(petsOver5))
{
Console.WriteLine($"\t{pet.Name} who is age {pet.Age}");
}
}
Live example: https://rextester.com/WUVVE89613
Upvotes: 0
Reputation: 12656
I would change the foreach section to:
people.ForEach(person=>
{
// Get all pets for this person that are older than 5
IEnumerable<Pet> pets = person.Pets.Where(pet => pet.Age > 5);
// If this person has any
if(pets.Count() != 0)
{
Console.WriteLine(person.LastName);
foreach(var p in pets)
{
Console.WriteLine(p.Name);
}
}
});
Upvotes: 0
Reputation: 10248
You either need to re-assign the where clause back to person.Pets (would permanently lose/remove any <= 5 pets though):
person.Pets = person.Pets.Where(pet => pet.Age > 5);
Store it locally:
var pets = person.Pets.Where(pet => pet.Age > 5);
And then iterate the local variable:
foreach(var p in pets)
Or foreach it inline instead:
foreach(var p in person.Pets.Where(pet => pet.Age > 5))
Upvotes: 0