package mods.betterfoliage.util import com.google.common.collect.ImmutableList import java.util.* /** * Starting with the second element of this [Iterable] until the last, call the supplied lambda with * the parameters (index, element, previous element). */ inline fun Iterable.forEachPairIndexed(func: (Int, T, T)->Unit) { var previous: T? = null forEachIndexed { idx, current -> if (previous != null) func(idx, current, previous!!) previous = current } } inline fun > Pair.minBy(func: (T)->C) = if (func(first) < func(second)) first else second inline fun > Pair.maxBy(func: (T)->C) = if (func(first) > func(second)) first else second inline fun > Triple.maxValueBy(func: (T)->C): C { var result = func(first) func(second).let { if (it > result) result = it } func(third).let { if (it > result) result = it } return result } inline fun Array.mapArray(func: (T)->R) = Array(size) { idx -> func(get(idx)) } @Suppress("UNCHECKED_CAST") inline fun Map.filterValuesNotNull() = filterValues { it != null } as Map inline fun Iterable.findFirst(func: (T)->R?): R? { forEach { func(it)?.let { return it } } return null } inline fun List>.filterIsInstanceFirst(cls: Class) = filter { it.first is A2 } as List> /** Cross product of this [Iterable] with the parameter. */ fun Iterable.cross(other: Iterable) = flatMap { a -> other.map { b -> a to b } } inline fun Iterable.mapAs(transform: (C) -> R) = map { transform(it as C) } inline fun forEachNested(list1: Iterable, list2: Iterable, func: (T1, T2)-> Unit) = list1.forEach { e1 -> list2.forEach { e2 -> func(e1, e2) } } /** Mutating version of _map_. Replace each element of the list with the result of the given transformation. */ inline fun MutableList.replace(transform: (T) -> T) = forEachIndexed { idx, value -> this[idx] = transform(value) } /** Exchange the two elements of the list with the given indices */ inline fun MutableList.exchange(idx1: Int, idx2: Int) { val e = this[idx1] this[idx1] = this[idx2] this[idx2] = e } /** Return a random element from the array using the provided random generator */ inline operator fun Array.get(random: Random) = get(random.nextInt(Int.MAX_VALUE) % size) fun Iterable.toImmutableList() = ImmutableList.builder().let { builder -> forEach { builder.add(it) } builder.build() }