namespace QWERTYkez.WordProcessor; internal static class IeExtension { /// /// Выполняет указанные действия для первого и последующих элементов последовательности. /// /// Тип элементов последовательности. /// Последовательность элементов. /// Действие над первым элементом (если есть). /// Действие над каждым последующим элементом, начиная со второго. /// Возникает, если items или любой из делегатов равен null. public static void ForFirstNext(this IEnumerable items, Action first, Action next) { if (items is null) throw new ArgumentNullException(nameof(items)); if (first is null) throw new ArgumentNullException(nameof(first)); if (next is null) throw new ArgumentNullException(nameof(next)); using var enumerator = items.GetEnumerator(); if (!enumerator.MoveNext()) return; first(enumerator.Current); while (enumerator.MoveNext()) { next(enumerator.Current); } } /// /// Выполняет указанные действия для первого, промежуточных и последнего элементов последовательности. /// Если последовательность содержит только один элемент, то для него вызываются и first, и last. /// /// Тип элементов последовательности. /// Последовательность элементов. /// Действие над первым элементом. /// Действие над элементами, которые не являются ни первыми, ни последними. /// Действие над последним элементом. /// Возникает, если items или любой из делегатов равен null. public static void ForFirstNextLast(this IEnumerable items, Action first, Action next, Action last) { if (items is null) throw new ArgumentNullException(nameof(items)); if (first is null) throw new ArgumentNullException(nameof(first)); if (next is null) throw new ArgumentNullException(nameof(next)); if (last is null) throw new ArgumentNullException(nameof(last)); using var enumerator = items.GetEnumerator(); if (!enumerator.MoveNext()) return; T firstItem = enumerator.Current; // Если только один элемент if (!enumerator.MoveNext()) { first(firstItem); last(firstItem); return; } // Есть как минимум два элемента first(firstItem); T prev = enumerator.Current; // второй элемент while (enumerator.MoveNext()) { next(prev); // предыдущий элемент точно не последний prev = enumerator.Current; } last(prev); // последний элемент } /// /// Выполняет указанные действия для всех элементов, кроме последнего, и для последнего элемента. /// Если последовательность содержит только один элемент, то вызывается только last. /// /// Тип элементов последовательности. /// Последовательность элементов. /// Действие над элементами, не являющимися последними. /// Действие над последним элементом. /// Возникает, если items или любой из делегатов равен null. public static void ForNextLast(this IEnumerable items, Action next, Action last) { if (items is null) throw new ArgumentNullException(nameof(items)); if (next is null) throw new ArgumentNullException(nameof(next)); if (last is null) throw new ArgumentNullException(nameof(last)); using var enumerator = items.GetEnumerator(); if (!enumerator.MoveNext()) return; T prev = enumerator.Current; while (enumerator.MoveNext()) { next(prev); prev = enumerator.Current; } last(prev); } }