c# - 如何通过自定义子字符串相等性仅迭代不同的字符串值

标签 c# linq iequalitycomparer

类似于this问题,我试图仅迭代给定字符串的子字符串的不同值,例如:

List<string> keys = new List<string>()
{
    "foo_boo_1",
    "foo_boo_2,
    "foo_boo_3,
    "boo_boo_1"
}

所选不同值的输出应该是(任意选择第一个子字符串的不同值):

foo_boo_1 (the first one)
boo_boo_1

我尝试实现 this使用 IEqualityComparer 的解决方案:

public class MyEqualityComparer : IEqualityComparer<string>
{
    public bool Equals(string x, string y)
    {            
        int xIndex = x.LastIndexOf("_"); 
        int yIndex = y.LastIndexOf("_");
        if (xIndex > 0 && yIndex > 0)
            return x.Substring(0, xIndex) == y.Substring(0, yIndex);
        else
            return false;
    }

    public int GetHashCode(string obj)
    {
        return obj.GetHashCode();
    }
}

foreach (var key in myList.Distinct(new MyEqualityComparer()))
{
    Console.WriteLine(key)    
}

但是结果输出是:

foo_boo_1
foo_boo_2
foo_boo_3
boo_boo_1

使用 IEqualityComparer 如何删除子字符串不同值(foo_boo_2foo_boo_3)?

*请注意,“真实”键要长得多,例如“1_0_8-B153_GF_6_2”,因此我必须使用 LastIndexOf。

最佳答案

您当前的实现存在一些缺陷:

  1. EqualsGetHashCode 必须永远不会抛出异常(您必须检查 null)
  2. 如果 Equals 对于 xy 返回 true,则 GetHashCode(x) == GetHashCode (y)反例“abc_1”“abc_2”

第二个错误很可能导致 Distinct 返回不正确的结果(Distinct 首先计算哈希值)。

正确的代码可能是这样的

public class MyEqualityComparer : IEqualityComparer<string> {
  public bool Equals(string x, string y) {            
    if (ReferenceEquals(x, y))
      return true;
    else if ((null == x) || (null == y))
      return false;

    int xIndex = x.LastIndexOf('_'); 
    int yIndex = y.LastIndexOf('_');

    if (xIndex >= 0)         
      return (yIndex >= 0) 
        ? x.Substring(0, xIndex) == y.Substring(0, yIndex)
        : false;
    else if (yIndex >= 0)         
      return false;
    else
      return x == y; 
  }

  public int GetHashCode(string obj) {
    if (null == obj)  
      return 0;

    int index = obj.LastIndexOf('_');

    return index < 0 
      ? obj.GetHashCode() 
      : obj.Substring(0, index).GetHashCode();
  }
}

现在您可以将其与 Distinct 一起使用:

   foreach (var key in myList.Distinct(new MyEqualityComparer())) {
     Console.WriteLine(key)    
   }

关于c# - 如何通过自定义子字符串相等性仅迭代不同的字符串值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60652120/

相关文章:

c# - 使用 Linq 关联防止空异常

.net - LINQ to Entities 无法识别“Boolean Contains”方法

c# - 使用 IEqualityComparer 的联合列表

c# - 在读卡器当前的智能卡上找到证书

c# - 如何防止 Zalgo 文本等变音符号

c# - VS2012无管理员账号远程调试

Linq to Entities 如何在一个数据库访问中更新记录

linq - 如何使用 LINQ 执行此使用列重命名(或列别名)的 SELECT 语句?

c# - 具有由 lambda 定义的自定义 IEqualityCompare 的 HashSet 构造函数?

c# - 当参数计数小于 List.Count 时出现 FindLastIndex ArgumentOutOfRangeException