Enumerable.Except与IEqualityComparer

时间:2014-10-13 18:45:20

标签: c# ienumerable except iequalitycomparer

我有两个字符串数组newArray和oldArray,我想使用Enumberable.Except方法删除newArray中同样位于oldArray中的所有项目,然后将结果写入csv文件。

但是,我需要使用自定义比较器来检查格式相似性(如果一个数组中没有新行字符而不是另一个,我不希望将该项写入文件)。 / p>

截至目前我的代码:

        string newString = File.ReadAllText(csvOutputFile1);
        string[] newArray = newString.Split(new string[] {sentinel}, StringSplitOptions.RemoveEmptyEntries);
        string oldString = File.ReadAllText(csvOutputFile2);
        string[] oldArray = oldString.Split(new string[] { sentinel }, StringSplitOptions.None);

        IEnumerable<string> differnceQuery = newArray.Except(oldArray, new Comparer());

        using (var wtr = new StreamWriter(diffFile))
        {
            foreach (var s in differnceQuery)
            {
                wtr.WriteLine(s.Trim() + "#!#");
            }
        }

和自定义比较器类:

class Comparer : IEqualityComparer<string>
{
    public bool Equals(string x, string y)
    {
        x = x.ToString().Replace(" ", "").Replace("\n", "").Replace("\r", "");
        y = y.ToString().Replace(" ", "").Replace("\n", "").Replace("\r", "");
        if (x == y)
            return true;
        else
            return false;
    }
    public int GetHashCode(string row)
    {
        int hCode = row.GetHashCode();
        return hCode;
    }
}

生成的文件没有省略两个数组之间的格式差异项。因此虽然它捕获了newArray中的项而不是oldArray中的项(就像它应该的那样),但它也只是因为一个\ n或者其他东西而放入了不同的项目,即使在我的自定义比较器中我正在删除它们。 / p>

我真正不理解的是当我调试并逐步执行代码时,我可以在自定义比较器类中看到每对项目都被分析,但只有当它们是相同的术语时。例如,如果字符串“这是第一个术语”在newArray中并且字符串“This is the first array”在oldArray中,则调试器甚至不会进入比较器类,而是直接跳转到我的writeline部分主类中的代码。

1 个答案:

答案 0 :(得分:3)

简单地说:你的哈希码没有正确地镜像你的相等方法。像"a b c""abc"这样的字符串会从GetHashCode返回不同的值,因此它永远不会绕过来测试EqualsGetHashCode 必须为任意两个可能相等的值返回相同的结果。但是,相等的两个字符串不必返回不同的哈希码(尽管非常需要,否则一切都会进入相同的哈希桶。)

你可以使用:

// warning: probably not very efficient
return x.Replace(" ", "").Replace("\n", "").Replace("\r", "").GetHashCode();

但这看起来相当昂贵(很有可能一直生成垃圾字符串)