简体   繁体   English

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

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

I am trying to return a boolean value if my object list contains all the types in a list of types in either vb.net or C#. 如果我的对象列表包含vb.net或C#中的类型列表中的所有类型,我试图返回一个布尔值。 I am struggling in writing a lambda expression to accomplish this. 我正在努力编写一个lambda表达式来完成此任务。 Can this be done using lambda predicates? 可以使用lambda谓词完成此操作吗? I know it can be done easily with a for each loop. 我知道每个循环都可以轻松完成。

vb.net 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# 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());
}

EDIT, thanks for all the quick answers, I see there are a few ways to do this, and now have a better understanding of what is happening in the expression. 编辑,感谢所有快速的回答,我发现有几种方法可以做到这一点,现在对表达式中发生的事情有了更好的了解。

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

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

Translated, it is true for all types in typeList that any (at least one) widget in the list has that type. 经过翻译,对于typeList中的所有类型, typeList中的任何(至少一个)小部件都具有该类型,这是事实。

I believe what you want is the following: 我相信您想要的是以下内容:

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

You can also use System.Linq as follows: 您还可以按如下方式使用System.Linq:

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

The shorter is 较短的是

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

or 要么

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

or 要么

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))

对于wList中的每个值,它将检查typeList中的任何值是否与wList方位值匹配。

You can use Intersect to check if both list has same values. 您可以使用“ Intersect来检查两个列表是否具有相同的值。 Try this code 试试这个代码

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

If you need to have hasAll == true only if all types in wList occured once, remove call to Distinct 如果仅当wList所有类型wList发生一次时才需要hasAll == true ,请删除对Distinct调用

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

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