我有两个字符串数组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部分主类中的代码。
答案 0 :(得分:3)
简单地说:你的哈希码没有正确地镜像你的相等方法。像"a b c"
和"abc"
这样的字符串会从GetHashCode
返回不同的值,因此它永远不会绕过来测试Equals
。 GetHashCode
必须为任意两个可能相等的值返回相同的结果。但是,不相等的两个字符串不必返回不同的哈希码(尽管非常需要,否则一切都会进入相同的哈希桶。)
我猜你可以使用:
// warning: probably not very efficient
return x.Replace(" ", "").Replace("\n", "").Replace("\r", "").GetHashCode();
但这看起来相当昂贵(很有可能一直生成垃圾字符串)