C#删除重复只检查字符串数组的第一个元素

时间:2016-06-17 02:54:21

标签: c# iequalitycomparer

我有一个字符串数组列表。我想通过仅检查字符串数组的第一个元素来删除重复项和空字符串。我已经看到一些使用IEqualityComparer的SO帖子来实现删除重复比较整个字符串数组,我认为它使它看起来更优雅,可能更有效。但是我没能在字符串数组的第一个元素上检查它以删除不需要的元素,因为IEqualityComparer让我困惑。我怎样才能更优雅地实现这一目标?我目前的非优雅&非效率的工作代码:

void method(List<string[]> contactAndNumber)
{
    List<string[]> contactAndNumberSanitized = new List<string[]>();
    contactAndNumberSanitized.Clear();
    bool rem = false;
    List<int> remList = new List<int>();
    for (int i = 0; i < contactAndNumber.Count; i++)
    {
        contactAndNumberSanitized.Add(new string[] { contactAndNumber[i][0], contactAndNumber[i][1] });
        for (int j = 0; j < contactAndNumberSanitized.Count; j++)
            if (i != j)
                if (contactAndNumber[i][0] == contactAndNumberSanitized[j][0])
                {
                    rem = true;
                    break;
                }
        if (rem || string.IsNullOrEmpty(contactAndNumber[i][0]))
            remList.Add(i);
        rem = false;
    }
    for (int i = remList.Count - 1; i >= 0; i--)
        contactAndNumberSanitized.RemoveAt(remList[i]);
}

这是我试图实现的非工作代码,只检查字符串数组的第一项:

sealed class EqualityComparer: IEqualityComparer<string[]>
{
    public bool Equals(string[] x, string[] y)
    {
        if (ReferenceEquals(x[0], y[0]))
            return true;

        if (x == null || y == null)
            return false;

        return x[0].SequenceEqual(y[0]);
    }

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

        int hash = 17;

        unchecked
        {
            foreach (string s in obj)
                hash = hash*23 + ((s == null) ? 0 : s.GetHashCode());
        }

        return hash;
    }
}

通过某种方法调用此方法:

var result = list.Distinct(new EqualityComparer());

2 个答案:

答案 0 :(得分:3)

您的代码可以大大简化:

var input = new List<string[]> { new[] { "a", "b" }, new[] { "a", "c" }, new[] { "c", "d" }};
var result = input.GroupBy(l => l.FirstOrDefault()).Select(g => g.First());

这将为您提供唯一的数组,使用每个数组的第一个元素来确定唯一性。

但是,由于您使用数组的第一个元素来确定唯一性,因此空集的边缘情况被视为等同于{ null }。根据您要处理空集的方式,您需要修改代码以过滤输入,或更改GroupBy

答案 1 :(得分:0)

由于您正在使用List&lt; T&gt;,因此您可以使用RemoveAll方法。

编辑:原始答案可能无效。修改如下。

编辑2:实际上,如果你想删除所有重复项(不离开原文),请使用:

var duplicates = data.Where(x => x == null || string.IsNullOrEmpty(x[0]) || data.Where(y => y != null).Count(y => y[0] == x[0]) > 1).ToList();
data.RemoveAll(x => duplicates.Contains(x));

但是如果你想把最后一个留在一组副本中(例如最后一个&#34; A&#34;在一组三个&#34; A&#34; s),那么你可以使用我原来的回答:

data.RemoveAll(x => x == null || string.IsNullOrEmpty(x[0]) || data.Where(y => y != null).Count(y => y[0] == x[0]) > 1);