Kotlin extension functions for Arrays and Lists

A collection of Kotlin extension methods that simplify many common tasks related to Arrays and Lists.

/**
 * Return a subrange of the array
 */
fun <T> Array<T>.range(range: IntRange): List<T> = this.filterIndexed { index, _ -> range.contains(index) }

fun <T> List<T>?.limit(n: Int): List<T> = this?.take(n) ?: emptyList()

fun <T> Stack<T>.peekOrNull() = if (this.empty()) null else this.peek()

fun List<*>.swap(fromPosition: Int, toPosition: Int) = Collections.swap(this, fromPosition, toPosition)

fun <T> List<T>.moveItem(sourceIndex: Int, targetIndex: Int) {
    if (sourceIndex <= targetIndex) {
        Collections.rotate(subList(sourceIndex, targetIndex + 1), -1)
    } else {
        Collections.rotate(subList(targetIndex, sourceIndex + 1), 1)
    }
}

fun <T> T.containedIn(dest: Array<T>) = dest.contains(this)

inline fun <T> MutableList<T>.mapInPlace(mutator: (T) -> T): MutableList<T> {
    val iterate = this.listIterator()
    while (iterate.hasNext()) {
        val oldValue = iterate.next()
        val newValue = mutator(oldValue)
        if (newValue !== oldValue) {
            iterate.set(newValue)
        }
    }
    return this
}

inline fun <T> Array<T>.mapInPlace(mutator: (T) -> T) {
    this.forEachIndexed { idx, value ->
        mutator(value).let { newValue ->
            if (newValue !== value) this[idx] = mutator(value)
        }
    }
}

fun <T> List<List<T>>.flatten(): ArrayList<T> {
    val merged = ArrayList<T>()
    this.forEach {
        merged.addAll(it)
    }
    return merged
}