确定HashSet包含不同的大小写字符串

本文关键字:大小写 字符串 包含不 HashSet String 确定 | 更新日期: 2023-09-27 18:11:29

我有一个很大的字符串集,其中包括许多重复的字符串。重要的是,所有的副本都有相同的外壳。所以这个集合将无法通过测试:

String[] strings = new String[] { "a", "A", "b", "C", "b" };

…但是这个测试会通过:

String[] strings = new String[] { "A", "A", "b", "C", "b" };

当我遍历strings中的每个字符串时,我的程序如何才能看到Aa的大小写不敏感副本(因此失败),但允许重复的b通过?

确定HashSet<String>包含不同的大小写字符串

一种简单的方法是创建两个集合——一个使用不区分大小写的字符串比较器,另一个使用区分大小写的比较器。(我不清楚你是否需要一个区域性敏感的字符串,或者在哪个区域性。)

构造后,如果两个集合的大小不同(Count),则必须有一些元素在不区分大小写的比较中相等,但在区分大小写的比较中不相等。

比如:

public static bool AllDuplicatesSameCase(IEnumerable<string> input)
{
    var sensitive = new HashSet<String>(input, StringComparer.InvariantCulture);
    var insensitive = new HashSet<String>(input, 
          StringComparer.InvariantCultureIgnoreCase);
    return sensitive.Count == insensitive.Count;
}

您可以显式地检查每个条目。

static bool DuplicatesHaveSameCasing(string[] strings)
{
  for (int i = 0; i < strings.Length; ++i)
  {
    for (int j = i + 1; j < strings.Length; ++j)
    {
      if (string.Equals(strings[i], strings[j], StringComparison.OrdinalIgnoreCase)
        && strings[i] != strings[j])
      {
        return false;
      }
    }
  }
  return true;
}

注释:我选择使用顺序比较。注意,!=运算符使用顺序和区分大小写的比较。将其更改为依赖于文化的比较非常简单。

另一个选项是使用LINQ。

                    //Group strings without considering case
bool doesListPass = strings.GroupBy(s => s.ToUpper())
                    //Check that all strings in each group has the same case
                    .All(group => group.All(s => group.First() == s));
                    //Group strings without considering case
IEnumerable<string> cleanedList = strings.GroupBy(s => s.ToUpper())
                    //Check that all strings in each group has the same case
                    .Where(group => group.All(s => group.First() == s))
                    //Map all the "passing" groups to a list of strings 
                    .SelectMany(g => g.ToList());

注意:您可以根据需要使用ToUpper()或ToUpperInvariant()