using System.Collections; using System.Globalization; namespace QWERTYkez.WordProcessor; /// /// Множество строк, которое автоматически приводит все добавляемые элементы /// к верхнему регистру и удаляет диакритические знаки (например, 'ё' -> 'Е'). /// Реализует ISet<string>, поэтому может использоваться там, где ожидается этот интерфейс. /// internal class NormalizedSet : ISet { private readonly HashSet _inner; /// /// Создаёт пустое нормализованное множество. /// public NormalizedSet() { _inner = []; } /// /// Создаёт нормализованное множество, заполненное элементами из указанной коллекции. /// /// Коллекция, элементы которой будут нормализованы и добавлены. public NormalizedSet(IEnumerable collection) { _inner = [.. collection.Select(Normalize)]; } /// /// Нормализует строку: верхний регистр и удаление диакритики. /// private static string Normalize(string s) { if (string.IsNullOrEmpty(s)) return s; var normalized = s.Normalize(NormalizationForm.FormD); var sb = new StringBuilder(); foreach (char c in normalized) { if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark) sb.Append(c); } return sb.ToString().Normalize(NormalizationForm.FormC).ToUpperInvariant(); } // ---------- Реализация ISet ---------- public bool Add(string item) => _inner.Add(Normalize(item)); void ICollection.Add(string item) => Add(item); public void UnionWith(IEnumerable other) { foreach (var item in other) Add(item); } public void IntersectWith(IEnumerable other) { var normalizedOther = new HashSet(other.Select(Normalize)); _inner.IntersectWith(normalizedOther); } public void ExceptWith(IEnumerable other) { var normalizedOther = new HashSet(other.Select(Normalize)); _inner.ExceptWith(normalizedOther); } public void SymmetricExceptWith(IEnumerable other) { var normalizedOther = new HashSet(other.Select(Normalize)); _inner.SymmetricExceptWith(normalizedOther); } public bool IsSubsetOf(IEnumerable other) { var normalizedOther = new HashSet(other.Select(Normalize)); return _inner.IsSubsetOf(normalizedOther); } public bool IsSupersetOf(IEnumerable other) { var normalizedOther = new HashSet(other.Select(Normalize)); return _inner.IsSupersetOf(normalizedOther); } public bool IsProperSupersetOf(IEnumerable other) { var normalizedOther = new HashSet(other.Select(Normalize)); return _inner.IsProperSupersetOf(normalizedOther); } public bool IsProperSubsetOf(IEnumerable other) { var normalizedOther = new HashSet(other.Select(Normalize)); return _inner.IsProperSubsetOf(normalizedOther); } public bool Overlaps(IEnumerable other) { var normalizedOther = new HashSet(other.Select(Normalize)); return _inner.Overlaps(normalizedOther); } public bool SetEquals(IEnumerable other) { var normalizedOther = new HashSet(other.Select(Normalize)); return _inner.SetEquals(normalizedOther); } // ---------- Реализация ICollection ---------- public int Count => _inner.Count; public bool IsReadOnly => false; public void Clear() => _inner.Clear(); public bool Contains(string item) => _inner.Contains(Normalize(item)); public void CopyTo(string[] array, int arrayIndex) => _inner.CopyTo(array, arrayIndex); public bool Remove(string item) => _inner.Remove(Normalize(item)); // ---------- Реализация IEnumerable и IEnumerable ---------- public IEnumerator GetEnumerator() => _inner.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); }