使用 lambda 谓词比较两个列表以确定两个列表是否包含相同的项目

Compare two lists to determine if both lists contain same items using lambda predicates

如果我的对象列表包含 vb.net 或 C# 类型列表中的所有类型,我将尝试 return 一个布尔值。我正在努力编写一个 lambda 表达式来实现这一点。这可以使用 lambda 谓词来完成吗?我知道可以通过 for each 循环轻松完成。

vb.net

Public Class Widget
    Public wobbly As String
    Public sprocket As String
    Public bearing As String
End Class

Public Sub test()
    Dim wList As New List(Of Widget)
    wList.Add(New Widget() With {.bearing = "xType", .sprocket = "spring", .wobbly = "99"})
    wList.Add(New Widget() With {.bearing = "yType", .sprocket = "sprung", .wobbly = "45"})
    wList.Add(New Widget() With {.bearing = "zType", .sprocket = "straight", .wobbly = "17"})

    Dim typeList As New List(Of String) From {"xType", "yType", "zType"}

    Dim containsAllTypes As Boolean = wList.TrueForAll(Function(a) a.bearing.Equals(typeList.Where(Function(b) b = a.bearing)))
    Debug.WriteLine(containsAllTypes.ToString)
End Sub

C#

public class Widget
{
    public string wobbly;
    public string sprocket;
    public string bearing;
}

public void test()
{
    List<Widget> wList = new List<Widget>();
    wList.Add(new Widget {
        bearing = "xType",
        sprocket = "spring",
        wobbly = "99"
    });
    wList.Add(new Widget {
        bearing = "yType",
        sprocket = "sprung",
        wobbly = "45"
    });
    wList.Add(new Widget {
        bearing = "zType",
        sprocket = "straight",
        wobbly = "17"
    });

    List<string> typeList = new List<string> {
        "xType",
        "yType",
        "zType"
    };

    bool containsAllTypes = wList.TrueForAll(a => a.bearing.Equals(typeList.Where(b => b == a.bearing)));
    Debug.WriteLine(containsAllTypes.ToString());
}

编辑,感谢所有快速回答,我看到有几种方法可以做到这一点,现在对表达式中发生的事情有了更好的理解。

var containsAll = typeList.All(type => 
    wList.Any(widget => widget.bearing.Equals(type)));

经过翻译,对于 typeList 中的所有类型,列表中的任何(至少一个)小部件都具有该类型。

较短的是

containsAllTypes = wList.Where(x => typeList.Contains(x.bearing)).Count() == typeList.Count;

containsAllTypes =  wList.Select(x => x.bearing).Except(typeList).Count() == 0;

containsAllTypes =  wList.Select(x => x.bearing).Intersect(typeList).Count() == typeList.Count;
 Dim containsAllTypes As Boolean = wList.All(Function(a) typeList.Any(Function(b) b = a.bearing))

对于 List 中的每个值,它检查类型 List 中的任何值是否与 wList 承载值相匹配。

您可以使用 Intersect 检查两个列表是否具有相同的值。试试这个代码

var hasAll = wList
 .Select(w => w.bearing)
 .Distinct()
 .Intersect(typeList)
 .Count() == typeList.Count;

如果仅当 wList 中的所有类型都出现一次时才需要 hasAll == true,请删除对 Distinct

的调用

尝试var containsAllTypes = typeList.All(x => wList.Select(x => x.bearing).Contains(x))

我相信你想要的是:

bool containsAllTypes1 = wList.TrueForAll(a => null != typeList.Find(b => b == a.bearing));

您还可以使用System.Linq,如下所示:

bool containsAllTypes2 = wList.All(a => typeList.Any(b => b == a.bearing));