using System; using System.Collections.Generic; using System.Linq; namespace ZeroLevel.Services.Collections { /// /// Циклический разреженный итератор /// позволяет выполнять циклический обход массива, с возможностью отмечать элементы /// которые требуется прпускать при следующих обходах. /// public class SparseIterator { private readonly T[] _array; private readonly HashSet _removed = new HashSet(); private int index = -1; public SparseIterator(IEnumerable items) { _array = items.ToArray(); } /// /// Текущий элемент последовательности /// public T Current { get { if (index >= 0 && index < _array.Length) { return _array[index]; } throw new IndexOutOfRangeException(); } } /// /// Указывает на отсутствие элементов в последовательности или на /// то что все элементы были отмечены для пропуска /// public bool IsEmpty { get { return _array.Length == 0 || _array.Length == _removed.Count; } } /// /// Сдвиг на следующий элемент, если достигнут конец последовательности, /// переключается на первый неотмеченный для пропуска элемент /// /// вернет -1 если последовательность пуста, или если не осталось элементов не отмеченных для пропуска public int MoveNext() { do { index++; } while (_removed.Contains(index)); if (index >= _array.Length) { if (IsEmpty) return -1; index = -1; do { index++; } while (_removed.Contains(index)); } return index; } /// /// Отмечает текущий элемент для пропуска при следующем обходе /// /// public bool Exclude() { if (index >= 0) { return _removed.Add(index); } return false; } } }