【问题标题】:How does one compare items in two lists?如何比较两个列表中的项目?
【发布时间】:2013-06-18 12:04:40
【问题描述】:

我遇到了一个我似乎无法解决的问题。我有两个相同类型的列表,我需要检查这些列表是否匹配。关于注释掉的 for 循环和现在使用的嵌套 foreach 循环,我遇到了问题。我不需要同时使用两者,一个是我想弄清楚的。

我已经通过调试器运行了这个,发现两个列表都包含相同的数据,我假设(使用 VS2010 调试器)在列表中的相同元素中。但是,当它被循环通过时,它会在第一个元素处失败。

我从类似的问题中对此进行了研究,但我对 LINQ 表达式不是很熟悉(我在业余时间做笔记以研究它)。

private bool ListMatch(List<T> list1, List<T> list2) 
    {
        if (list1 == null && list2 == null)
        {
            return true;
        }
        if ((list1 == null) || (list2 == null))
        {
            return false;
        }
    if (list1.Count != list2.Count)
    {
        return false;
    }
    if( list1.Equals( list2 ) )
    {
        return true;
    }

    /*for (var idx = 0; idx < list1.Count; idx++)
    {
        if( list1[ idx ] != list2[ idx ] )
        {
            return false;
        }
    }*/

    foreach( var x in list1 )
    {
        bool hasDuplicates = false;
        foreach( var y in list2 )
        {

            if( x == y )
            {
                hasDuplicates = true;
                break;
            }
        }

        if( hasDuplicates )
        {
            return true;
        }
        return false;
    }

    return true;
}

【问题讨论】:

  • 您是在比较参考,而不是值。这是你想做的吗?
  • 你的 if( hasDuplicates )return 如果有重复与否..这就是它在第一个元素上失败的原因。它正在检查第一个元素,它是否重复?返回真。它不是?返回假。它不检查其余部分。
  • 我认为代码甚至都不会编译,更不用说进行参考比较了:你不能写x == y,因为它们是泛型的。

标签: c# list compare


【解决方案1】:

您可以在手动预检查相等性后使用Enumerable.SequenceEqual

private bool ListMatch(List<T> list1, List<T> list2) 
{
    if (list1 == null && list2 == null)        
        return true;

    if ((list1 == null) || (list2 == null))        
        return false;        

    if (list1.Count != list2.Count)    
        return false;    

    if(list1.Equals(list2))        
        return true;

    return Enumerable.SequenceEqual(list1, list2);
}

【讨论】:

  • +1,我会投赞成票,但我没有足够的代表。这与@william 解决方案一起确实让我更好地理解。我得到了一个错误的答案(需要它是真的),但这超出了这个问题的范围。谢谢!
【解决方案2】:

第二个循环有很多bug,不要用^^

您可以使用list1.SequenceEqual(list2) 来检查列表是否相等(假设顺序很重要,它看起来很重要)。

【讨论】:

    【解决方案3】:

    您正在比较这些索引中列表的引用。你可以这样做 Except 运算符将返回一个列表,其中包含两个列表中都不存在的元素,即差异。如果您需要将它们用于某事,这很有用

    List<T> result = list1.Except(list2).ToList();
    if (result.count == 0)
    //No differences
    return true;
    else
    //Differences
    return false;
    

    【讨论】:

      【解决方案4】:

      你不应该使用==,因为默认情况下这是引用相等,听起来你的算法失败了,因为你真的想要值相等;使用Object.Equals 并覆盖它。也就是说,framework does this for you(假设您希望两个列表以相同的顺序具有相同的项目)。将您的循环和之后的所有内容替换为:

      return list1.SequenceEqual(list2);
      

      您需要确保 Object.Equals 被列表中的元素类型覆盖(或者它们实现了 IEquatable&lt;T&gt;),否则您将遇到与代码中的问题之一相同的问题。

      或者,有一个overload 可以让你传递如何比较相等如果你需要一些特殊的东西或者不想覆盖Object.Equals

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多