I have a list of Fruit
which has name and price value.
public class Fruit {
public string name {get; set;}
public int price {get; set;}
public Fruit(string n, int p)
{
name = n;
price = p;
}
...
}
List<Fruit> myBasket = new List<Fruit>();
myBasket.Add(new Fruit("apple", 300));
myBasket.Add(new Fruit("banana", 200));
myBasket.Add(new Fruit("kiwi", 400));
Also, there is a list of average market price of fruits.
List<Fruit> averagePrice = new List<Fruit>();
averagePrice.Add(new Fruit("apple", 500));
averagePrice.Add(new Fruit("banana", 100));
averagePrice.Add(new Fruit("kiwi", 600));
What I want to do is to filter myBasket to have only fruit that is lower price than averagePrice.
So, in the example, myBasket will have apple and kiwi.
I tried myBasket = myBasket.Where(v => v.price < averagePrice.FirstOrDefault(y => y.name.Equals(v.name)).price).ToList();
.
It works well, but has a possibility of null pointer exception when there is new fruit in myBasket
but not in averagePrice
.
How can I change it to prevent it from exception?
Thanks in advance.
This seems to be quite a simple way to do it:
myBasket =
(
from f in myBasket
join a in averagePrice on f.name equals a.name
where f.price < a.price
select f
).ToList();
That gives me:
Here's the equivalent method-syntax:
myBasket =
myBasket
.Join(averagePrice, f => f.name, a => a.name, (f, a) => new { f, a })
.Where(x => x.f.price < x.a.price)
.Select(x => x.f)
.ToList();
Comprehension query syntax
Func<Fruit, bool> take = (fruit) =>
{
var query = averagePrice.Where(f => f.name == fruit.name);
return query.Count() == 0 ? true : fruit.price <= query.Min(f => f.price);
};
var result = from fruit in myBasket
where take(fruit)
orderby fruit.name
select fruit;
foreach ( var item in result )
Console.WriteLine($"{item.name}: {item.price}");
For each fruit in the basket we search it in the average list and take the minimum price available to compare it.
It may be possible to optimize this query with advanced functions like joins and projections or other...
Output
apple: 300
kiwi: 400
Output without average banana
apple: 300
banana: 200
kiwi: 400
Lambda query version
var result = myBasket.Where(fruit =>
{
var query = averagePrice.Where(f => f.name == fruit.name);
return query.Count() == 0 ? true : fruit.price <= query.Min(f => f.price);
});
foreach ( var item in result.OrderBy(f => f.name) )
Console.WriteLine($"{item.name}: {item.price}");
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.