自定义类的List.except

nik*_*nik 6 c# linq

假设我有一个自定义类:

public class WineCellar
{

    public string year;
    public string wine;
    public double nrbottles;
}
Run Code Online (Sandbox Code Playgroud)

可以说我现在有一个这个自定义类的列表:

List<WineCellar> orignialwinecellar = List<WineCellar>();
Run Code Online (Sandbox Code Playgroud)

包含这些项目:

2012 Chianti 12

2011 Chianti 6

2012 Chardonay 12

2011 Chardonay 6
Run Code Online (Sandbox Code Playgroud)

我知道,如果我想比较两个列表并返回一个新列表,其中只包含不在其他列表中的项目,我会这样做:

var newlist = list1.Except(list2);
Run Code Online (Sandbox Code Playgroud)

如何将其扩展到自定义类?让我们说:

string[] exceptionwinelist = {"Chardonay", "Riesling"};
Run Code Online (Sandbox Code Playgroud)

我想要退回:

List<WineCellar> result = originalwinecellar.wine.Except(exceptionwinelist);
Run Code Online (Sandbox Code Playgroud)

这个伪代码显然不起作用,但希望能说明我想做的事情.然后,该shoudl返回自定义类winecellar的List,其中包含以下项:

2012年基安蒂12

2011年基安蒂6

谢谢.

Jon*_*Jon 16

你真的不想在Except这里使用,因为你没有WineCellar用作黑名单的对象集合.你所拥有的是一系列规则:"我不想要具有这种和这样的葡萄酒名称的物品".

因此,最好简单地使用Where:

List<WineCellar> result = originalwinecellar
    .Where(w => !exceptionwinelist.Contains(w.wine))
    .ToList();
Run Code Online (Sandbox Code Playgroud)

以人类可读的形式:

我想要所有WineCellars,其中葡萄酒名称不在例外列表中.

顺便说一下,WineCellar班级名称有点误导; 那些物品不是酒窖,它们是库存物品.

  • 如果您经常这样做,或者异常列表包含许多项,您可能希望将异常列表存储为`HashSet <string>`以使`Contains`函数更快.但是,与往常一样,将两种方法作为"HashSet"进行基准测试确实具有不可忽略的创建成本. (4认同)

Dar*_*mas 5

一种解决方案是使用扩展方法:

public static class WineCellarExtensions
{
    public static IEnumerable<WineCellar> Except(this List<WineCellar> cellar, IEnumerable<string> wines)
    {
        foreach (var wineCellar in cellar)
        {
            if (!wines.Contains(wineCellar.wine))
            {
                yield return wineCellar;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:

List<WineCellar> result = originalwinecellar.Except(exceptionwinelist).ToList();
Run Code Online (Sandbox Code Playgroud)