using System.Collections.Generic; using System.Linq; using Mammoth.Couscous.java.lang; using Mammoth.Couscous.java.util; using Mammoth.Couscous.java.util.function; namespace Mammoth.Couscous.org.zwobble.mammoth.@internal.util { internal static class Iterables { internal static Optional getFirst(Iterable iterable) { var iterator = iterable.iterator(); if (iterator.hasNext()) { return Optional.of(iterator.next()); } else { return Optional.empty(); } } internal static T getFirst(Iterable iterable, T defaultValue) { var iterator = iterable.iterator(); if (iterator.hasNext()) { return iterator.next(); } else { return defaultValue; } } internal static Optional tryGetLast(Iterable iterable) where T : class { var hasElement = false; T last = null; var iterator = iterable.iterator(); while (iterator.hasNext()) { hasElement = true; last = iterator.next(); } if (hasElement) { return Optional.of(last); } else { return Optional.empty(); } } internal static Optional tryFind(Iterable iterable, Predicate predicate) { var iterator = iterable.iterator(); while (iterator.hasNext()) { T value = iterator.next(); if (predicate.test(value)) { return new Some(value); } } return None.Instance; } internal static OptionalInt findIndex(Iterable iterable, Predicate predicate) { var iterator = iterable.iterator(); int index = 0; while (iterator.hasNext()) { T value = iterator.next(); if (predicate.test(value)) { return new SomeInt(index); } index++; } return NoneInt.Instance; } internal static Iterable lazyFilter(Iterable iterable, Predicate predicate) { var enumerable = FromJava.IterableToEnumerable(iterable).Where(predicate.test); return ToJava.EnumerableToIterable(enumerable); } internal static Iterable lazyFilter(Iterable iterable, System.Type type) { var enumerable = FromJava.IterableToEnumerable(iterable).OfType(); return ToJava.EnumerableToIterable(enumerable); } internal static Iterable lazyMap(Iterable iterable, Function function) { var enumerable = FromJava.IterableToEnumerable(iterable) .Select(function.apply); return ToJava.EnumerableToIterable(enumerable); } internal static Iterable lazyFlatMap(Iterable iterable, Function> function) { var enumerable = FromJava.IterableToEnumerable(iterable) .SelectMany(element => FromJava.IterableToEnumerable(function.apply(element))); return ToJava.EnumerableToIterable(enumerable); } internal static Iterable lazyConcat(Iterable first, Iterable second) { var enumerable = FromJava.IterableToEnumerable(first) .Concat(FromJava.IterableToEnumerable(second)); return ToJava.EnumerableToIterable(enumerable); } internal static Iterable intRange(int start, int end) { return new IntRange(start, end); } private class IntRange : Iterable { private readonly int _start; private readonly int _end; internal IntRange(int start, int end) { _start = start; _end = end; } public Iterator iterator() { return new IntRangeIterator(_start, _end); } } private class IntRangeIterator : Iterator { private int _next; private readonly int _end; internal IntRangeIterator(int start, int end) { _next = start; _end = end; } public bool hasNext() { return _next < _end; } public int next() { return _next++; } } } }