Files
QWERTYkez.OpenXmlProcessors/QWERTYkez.WordProcessor/NormalizedSet.cs

135 lines
4.6 KiB
C#
Raw Normal View History

using System.Collections;
using System.Globalization;
namespace QWERTYkez.WordProcessor;
/// <summary>
/// Множество строк, которое автоматически приводит все добавляемые элементы
/// к верхнему регистру и удаляет диакритические знаки (например, 'ё' -> 'Е').
/// Реализует ISet&lt;string&gt;, поэтому может использоваться там, где ожидается этот интерфейс.
/// </summary>
2026-06-08 14:31:31 +07:00
internal class NormalizedSet : ISet<string>
{
private readonly HashSet<string> _inner;
/// <summary>
/// Создаёт пустое нормализованное множество.
/// </summary>
public NormalizedSet()
{
_inner = [];
}
/// <summary>
/// Создаёт нормализованное множество, заполненное элементами из указанной коллекции.
/// </summary>
/// <param name="collection">Коллекция, элементы которой будут нормализованы и добавлены.</param>
public NormalizedSet(IEnumerable<string> collection)
{
_inner = [.. collection.Select(Normalize)];
}
/// <summary>
/// Нормализует строку: верхний регистр и удаление диакритики.
/// </summary>
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<string> ----------
public bool Add(string item) => _inner.Add(Normalize(item));
void ICollection<string>.Add(string item) => Add(item);
public void UnionWith(IEnumerable<string> other)
{
foreach (var item in other)
Add(item);
}
public void IntersectWith(IEnumerable<string> other)
{
var normalizedOther = new HashSet<string>(other.Select(Normalize));
_inner.IntersectWith(normalizedOther);
}
public void ExceptWith(IEnumerable<string> other)
{
var normalizedOther = new HashSet<string>(other.Select(Normalize));
_inner.ExceptWith(normalizedOther);
}
public void SymmetricExceptWith(IEnumerable<string> other)
{
var normalizedOther = new HashSet<string>(other.Select(Normalize));
_inner.SymmetricExceptWith(normalizedOther);
}
public bool IsSubsetOf(IEnumerable<string> other)
{
var normalizedOther = new HashSet<string>(other.Select(Normalize));
return _inner.IsSubsetOf(normalizedOther);
}
public bool IsSupersetOf(IEnumerable<string> other)
{
var normalizedOther = new HashSet<string>(other.Select(Normalize));
return _inner.IsSupersetOf(normalizedOther);
}
public bool IsProperSupersetOf(IEnumerable<string> other)
{
var normalizedOther = new HashSet<string>(other.Select(Normalize));
return _inner.IsProperSupersetOf(normalizedOther);
}
public bool IsProperSubsetOf(IEnumerable<string> other)
{
var normalizedOther = new HashSet<string>(other.Select(Normalize));
return _inner.IsProperSubsetOf(normalizedOther);
}
public bool Overlaps(IEnumerable<string> other)
{
var normalizedOther = new HashSet<string>(other.Select(Normalize));
return _inner.Overlaps(normalizedOther);
}
public bool SetEquals(IEnumerable<string> other)
{
var normalizedOther = new HashSet<string>(other.Select(Normalize));
return _inner.SetEquals(normalizedOther);
}
// ---------- Реализация ICollection<string> ----------
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<string> и IEnumerable ----------
public IEnumerator<string> GetEnumerator() => _inner.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}