namespace BakaIterator { using System; using System.Collections.Generic; using System.Linq; public class BakaIterator { public T Current => _items[_index]; public bool HasNext => _index + 1 < _items.Count - 1; public int Position => _index; public int Count => _items.Count; public BakaIterator(IList items) { if (items is null) { throw new ArgumentNullException(nameof(items)); } if (items.Count == 0) { throw new ArgumentException("Items must contain at least 1 element", nameof(items)); } _items = items; _index = 0; } private readonly IList _items; private int _index; public BakaIterator MoveForward(int steps = 1) { if (steps < 0) { throw new ArgumentException("Invalid steps count. Must be 0 or positiv integer"); } if (_index + steps > _items.Count - 1) { throw new IndexOutOfRangeException("To many steps"); } _index += steps; return this; } public BakaIterator MoveBackwards(int steps = 1) { if (steps < 0) { throw new ArgumentException("Invalid steps count. Must be 0 or positiv integer"); } if (_index - steps < 0) { throw new IndexOutOfRangeException("To many steps"); } _index -= steps; return this; } public BakaIterator Reset() { _index = 0; return this; } public BakaIterator First(Func predicate, bool throwIfNotFound = true) { do { if (predicate(Current))//Мы уже получили этот элемент { return this; } if (HasNext) { MoveForward(); } } while (HasNext); if (throwIfNotFound) { throw new Exception("Item not found"); } return this; } //Для случая если нам нужен не просто первый, но первый который не текущий public BakaIterator FirstNext(Func predicate, bool throwIfNotFound = true) { return First((x) => predicate(x) && Current.Equals(x) == false, throwIfNotFound); } public BakaIterator ThrowIf(Func predicate) { if (predicate(Current)) { throw new Exception($"Item {Current} is "); } return this; } public BakaIterator ThrowIfNot(Func predicate) { if (!predicate(Current)) { throw new Exception("Current item is not"); } return this; } public BakaIterator ForEachFromCurrent(Action action) { foreach(var i in _items.Skip(_index + 1)) { action(i); } return this; } public BakaIterator ForEach(Action action) { foreach (var i in _items) { action(i); } return this; } } }