简体   繁体   English

如何通过使用 C# 中的 Linq 比较另一个列表中的值来过滤列表?

[英]How to filter a list by comparing a value from another list using Linq in C#?

I have a list of Fruit which has name and price value.我有一个包含名称和价格值的Fruit列表。

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.我想要做的是过滤 myBasket,使其只有价格低于平均价格的水果。

So, in the example, myBasket will have apple and kiwi.因此,在示例中,myBasket 将包含 apple 和 kiwi。

I tried myBasket = myBasket.Where(v => v.price < averagePrice.FirstOrDefault(y => y.name.Equals(v.name)).price).ToList();我试过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 .它运行良好,但当 myBasket 中有新水果但myBasket中没有新水果时,可能会出现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 Output

apple: 300
kiwi: 400

Output without average banana Output 不带平均香蕉

apple: 300
banana: 200
kiwi: 400

Lambda query version Lambda查询版

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}");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM