【问题标题】:Compare two lists to determine if both lists contain same items using lambda predicates使用 lambda 谓词比较两个列表以确定两个列表是否包含相同的项目
【发布时间】:2019-03-06 19:09:18
【问题描述】:

如果我的对象列表包含 vb.net 或 C# 中类型列表中的所有类型,我将尝试返回一个布尔值。我正在努力编写一个 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());
}

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

【问题讨论】:

  • 如果wList 包含两个带有xType 的项目怎么办?您当前的代码有什么问题?你能展示(在 c# 伪代码中)你想要达到的目标吗?

标签: c# .net vb.net lambda predicate


【解决方案1】:

试试var containsAllTypes = typeList.All(x =&gt; wList.Select(x =&gt; x.bearing).Contains(x))

【讨论】:

  • 这个解决方案也有效,我认为使用Contains 或使用Any 的Scott Hannen 的回答基本相同,只要它以All 谓词为前缀,所以检查每一个。
【解决方案2】:
var containsAll = typeList.All(type => 
    wList.Any(widget => widget.bearing.Equals(type)));

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

【讨论】:

  • 我正在尝试验证列表中是否存在所有类型,而不仅仅是一种。
  • 是的,这是我的理解。对于typeList 中的所有类型,wList 中必须至少有一个匹配的小部件。
  • 也许我没有尽可能清楚地说明它,但我想确保typeList 中的所有项目都对应于wList 中的一个项目,以便我比较@ 中的每个项目987654327@ 以确保它也在typeList
  • 在这种情况下,我认为答案的数量表明缺乏明确性。 “如果我的对象列表包含类型列表中的所有类型。”如果wList 包含typeList 中的所有类型?这是我的理解。
  • 好的,在检查了你的逻辑之后,我看到了它现在在做什么,起初我以为它只是检查 any 是否存在其中一种类型,但我知道它是如何使用 @ 987654332@ 然后做有条件的
【解决方案3】:

我相信您想要的是以下内容:

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

【讨论】:

    【解决方案4】:
     Dim containsAllTypes As Boolean = wList.All(Function(a) typeList.Any(Function(b) b = a.bearing))
    

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

    【讨论】:

      【解决方案5】:

      较短的是

      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;
      

      【讨论】:

        【解决方案6】:

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-06
          • 2013-12-28
          • 1970-01-01
          • 1970-01-01
          • 2022-01-08
          • 1970-01-01
          相关资源
          最近更新 更多