【问题标题】:Let the SequenceEqual Work for the list让 SequenceEqual 为列表工作
【发布时间】:2009-06-16 02:34:50
【问题描述】:

我有一个名为 Country 的班级。它有公共成员“CountryName”和“States”。

我已经宣布了一个国家列表。

现在我想编写一个函数,它接受一个新的“国家”并确定 CountryList 是否已经有“国家”。

我试着写一个类似的函数

bool CheckCountry(Country c)
{
    return CountryList.Exists(p => p.CountryName == c.Name
                                && p.States.SequenceEqual(c.States));
}

由于我想使用州的 CountryName 属性比较州,我想修改我的函数,以便 SequenceEqual 基于州的 CountryName 工作?

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    将其分解为许多简单的查询,然后将这些查询重新组合在一起。

    让我们从创建一个按名称匹配的项目序列开始:

    var nameMatches = from item in itemList where item.Name == p.Name select item;
    

    我们需要将这些项目与 p 的子项目中的名称序列进行比较。那是什么顺序? 编写查询:

    var pnames = from subitem in p.SubItems select subitem.Name;
    

    现在您要从 nameMatches 中查找名称序列匹配的所有元素。你将如何获得名称的序列?好吧,我们刚刚看到了如何使用 pnames 来做到这一点,所以做同样的事情:

    var matches = from item in nameMatches
                  let subitemNames = 
                      (from subitem in item.SubItems select subitem.Name)
                  where pnames.SequenceEqual(subitemNames)
                  select item;
    

    现在你想知道,有匹配的吗?

    return matches.Any();
    

    这应该可以正常工作。但是,如果您想成为真正的爱好者,您可以在一个大查询中编写整个内容!

    return (
        from item in itemList
        let pnames = 
            (from psubitem in p.SubItems select psubitem.Name)
        let subitemNames = 
            (from subitem in item.SubItems select subitem.Name)
        where item.Name == p.Name
        where pnames.SequenceEqual(subitemNames)
        select item).Any();
    

    你就完成了。易如反掌!请记住,将其分解为小步骤,单独解决每个问题,然后将解决方案从小结果中组合出来。

    【讨论】:

    • 我真的想知道这是否是 C# 团队中的某个人在阅读时编写的。事实证明:Eric Lippert 当然是 C# 团队的成员!
    【解决方案2】:

    您是否考虑过在 Item 上实现 IComparer?

    【讨论】:

      【解决方案3】:

      如果我理解正确,您想要一种比较两个项目的方法,首先检查两个项目的名称,然后依次检查每个子项目的名称。这就是你想要的:

          public override bool Equals(object obj)
          {
              return this.Name == (obj as Item).Name;
          }
          public override int GetHashCode()
          {
              return this.Name.GetHashCode();
          }
          public bool Check(Item obj)
          {
              if (this.Name != obj.Name)
                  return false;
              //if the lists arent of the same length then they 
              //obviously dont contain the same items, and besides 
              //there would be an exception on the next check
              if (this.SubItems.Count != obj.SubItems.Count)
                  return false;
              for (int i = 0; i < this.SubItems.Count; i++)
                  if (this.SubItems[i] != obj.SubItems[i])
                      return false;
              return true;
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-11-09
        • 1970-01-01
        • 2016-01-14
        • 2013-12-24
        • 1970-01-01
        • 1970-01-01
        • 2014-05-13
        相关资源
        最近更新 更多