I have 3 classes with the following properties:
OfferList class:
Guid Id
IEnumerable<Offer> Offers
Offer class:
Guid Id
Product Product
bool IsSealed
Product class:
Guid Id
An OfferList contains multiple Offers and an Offer has exact 1 Product.
How can I filter the OfferList to contain only Offers which are not sealed?
OfferList offerList = this.GetOfferList(id).Offers.Where(o => !o.IsSealed));
This returns an IEnumerable of type Offer instead of filtering the OfferList.
C# filter list with iteration. In the first example, we use a foreach loop to filter a list. var words = new List<string> { "sky", "rock", "forest", "new", "falcon", "jewelry" }; var filtered = new List<string>(); foreach (var word in words) { if (word. Length == 3) { filtered.
IEnumerable is an interface defining a single method GetEnumerator() that returns an IEnumerator interface. It is the base interface for all non-generic collections that can be enumerated. This works for read-only access to a collection that implements that IEnumerable can be used with a foreach statement.
Interesting - it is a little confusing what you're asking here.
I think you're asking how to have Offers
filtered in-place. If so:
IEnumerable<T>
is immutable (you have to cast to a concrete List<T>
or similar to get mutability), and Offers
is an IEnumerable<T>
- so you can't expect Offers.Where(o => !o.IsSealed));
to change the Offers
property - it returns an enumerable that filters the source as you enumerate it.
Instead you'd do
var offerList = this.GetOfferList(id)
offerList.Offers = offerList.Offers.Where(o => !o.IsSealed));
Note, however, that this hides the original Offers
reference for any other code sharing that OfferList
instance. It also doesn't actually do any filtering until you start enumerating, either. But that's often preferable. If you want it done there and then - use .ToArray()
or .ToList()
at the end of the Where
to force the enumeration to be done.
A better approach would be to have a property or method on the OfferList
class that returns a new enumerable on-demand:
public IEnumerable<Offer> UnsealedOffers {
get {
return Offers.Where(o => !o.IsSealed);
}
}
That way you're not destroying the master enumerable.
Note that this code is susceptible to Offers
being null (a NullReferenceException
) and that it's not great to return null enumerables (return empty ones instead) - so if there is a chance that Offers
can be null - then either stop that from happening; or use:
return (Offers ?? Enumerable.Empty<Offer>()).Where(o => !o.IsSealed);
If you mean that you want to update your original OfferList
instance, you could just assign the filtered sequence to its Offers
field:
OfferList offerList = this.GetOfferList(id);
offerList.Offers = offerList.Offers.Where(o => !o.IsSealed);
Do you need a new list of un-sealed offers?
List<Offer> offers = this.GetOfferList(id).Offers
.Where(o => !o.IsSealed)
.ToList();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With