【问题标题】:Determine if string appears more than once in string array (C#)确定字符串是否在字符串数组中多次出现(C#)
【发布时间】:2011-09-06 10:35:20
【问题描述】:

我有一个字符串数组,f.e.

string [] letters = { "a", "a", "b", "c" };

我需要找到一种方法来确定数组中的任何字符串是否多次出现。 我认为最好的方法是创建一个没有相关字符串的新字符串数组并使用包含,

foreach (string letter in letters)
{
    string [] otherLetters = //?
    if (otherLetters.Contains(letter))
    {
        //etc.     
    }
}

但我不知道怎么做。 如果有人对此有解决方案或更好的方法,请回答。

【问题讨论】:

    标签: c# arrays string


    【解决方案1】:

    最简单的方法是使用GroupBy

    var lettersWithMultipleOccurences = letters.GroupBy(x => x)
                                               .Where(g => g.Count() > 1)
                                               .Select(g => g.Key);
    

    这将首先使用字母作为键对您的数组进行分组。然后它只返回具有多个条目的那些组并返回这些组的键。结果,您将拥有一个IEnumerable<string>,其中包含在原始数组中多次出现的所有字母。在您的示例中,这只是“a”。

    注意:由于 LINQ 是使用延迟执行实现的,因此多次枚举 lettersWithMultipleOccurences 将执行多次分组和过滤。为避免这种情况,请在结果上调用ToList()

    var lettersWithMultipleOccurences = letters.GroupBy(x => x)
                                               .Where(g => g.Count() > 1)
                                               .Select(g => g.Key).
                                               .ToList();
    

    lettersWithMultipleOccurences 现在将是 List<string> 类型。

    【讨论】:

      【解决方案2】:

      您可以使用 LINQ 扩展方法:

      if (letters.Distinct().Count() == letters.Count()) {
          // no duplicates
      }
      

      Enumerable.Distinct 删除重复项。因此,letters.Distinct() 将在您的示例中返回三个元素。

      【讨论】:

      • 使用数组的 .Length 属性 (letters.Length) 更有效一点,无需扩展 - 但肯定这是最优雅和最有效的方式。
      • @Shadow:好点。不过,出于美学原因,我将把它留在Count(),因为在左侧使用Count() 并在右侧使用Length 看起来很奇怪。
      • 这并不重要。 Enumerable.Count() 使用 Count 属性,如果输入是 ICollectionICollection<T> 并且 .NET 数组是两者。
      【解决方案3】:

      从数组中创建一个HashSet 并比较它们的大小:

      var set = new HashSet(letters);
      bool hasDoubleLetters = set.Size == letters.Length;
      

      【讨论】:

        【解决方案4】:

        HashSet 会给你带来很好的性能:

        HashSet<string> hs = new HashSet<string>();
        foreach (string letter in letters)
        {
            if (hs.Contains(letter))
            {
                //etc. more as once     
            }
            else
            {
                   hs.Add(letter);
            }
        }
        

        【讨论】:

        • 这大约比我的代码长五倍,不一定更高效。
        • 这取决于初始数组的填充和大小。
        猜你喜欢
        • 1970-01-01
        • 2017-06-16
        • 2012-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-20
        相关资源
        最近更新 更多