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;
}
}
}