Add mapIndexed() function for common case withIndex().map{} #KT-3153 Fixed

This commit is contained in:
Ilya Ryzhenkov
2014-12-15 21:53:34 +03:00
parent 846014b37f
commit f4b96a0a1a
5 changed files with 301 additions and 15 deletions
+240 -13
View File
@@ -560,6 +560,233 @@ public inline fun <R> String.map(transform: (Char) -> R): List<R> {
return mapTo(ArrayList<R>(), transform)
}
/**
* Returns a list containing the results of applying the given *transform* function to each element and its index of the original collection
*/
public inline fun <T, R> Array<out T>.mapIndexed(transform: (Int, T) -> R): List<R> {
return mapIndexedTo(ArrayList<R>(), transform)
}
/**
* Returns a list containing the results of applying the given *transform* function to each element and its index of the original collection
*/
public inline fun <R> BooleanArray.mapIndexed(transform: (Int, Boolean) -> R): List<R> {
return mapIndexedTo(ArrayList<R>(), transform)
}
/**
* Returns a list containing the results of applying the given *transform* function to each element and its index of the original collection
*/
public inline fun <R> ByteArray.mapIndexed(transform: (Int, Byte) -> R): List<R> {
return mapIndexedTo(ArrayList<R>(), transform)
}
/**
* Returns a list containing the results of applying the given *transform* function to each element and its index of the original collection
*/
public inline fun <R> CharArray.mapIndexed(transform: (Int, Char) -> R): List<R> {
return mapIndexedTo(ArrayList<R>(), transform)
}
/**
* Returns a list containing the results of applying the given *transform* function to each element and its index of the original collection
*/
public inline fun <R> DoubleArray.mapIndexed(transform: (Int, Double) -> R): List<R> {
return mapIndexedTo(ArrayList<R>(), transform)
}
/**
* Returns a list containing the results of applying the given *transform* function to each element and its index of the original collection
*/
public inline fun <R> FloatArray.mapIndexed(transform: (Int, Float) -> R): List<R> {
return mapIndexedTo(ArrayList<R>(), transform)
}
/**
* Returns a list containing the results of applying the given *transform* function to each element and its index of the original collection
*/
public inline fun <R> IntArray.mapIndexed(transform: (Int, Int) -> R): List<R> {
return mapIndexedTo(ArrayList<R>(), transform)
}
/**
* Returns a list containing the results of applying the given *transform* function to each element and its index of the original collection
*/
public inline fun <R> LongArray.mapIndexed(transform: (Int, Long) -> R): List<R> {
return mapIndexedTo(ArrayList<R>(), transform)
}
/**
* Returns a list containing the results of applying the given *transform* function to each element and its index of the original collection
*/
public inline fun <R> ShortArray.mapIndexed(transform: (Int, Short) -> R): List<R> {
return mapIndexedTo(ArrayList<R>(), transform)
}
/**
* Returns a list containing the results of applying the given *transform* function to each element and its index of the original collection
*/
public inline fun <T, R> Iterable<T>.mapIndexed(transform: (Int, T) -> R): List<R> {
return mapIndexedTo(ArrayList<R>(), transform)
}
/**
* Returns a stream containing the results of applying the given *transform* function to each element and its index of the original stream
*/
public fun <T, R> Stream<T>.mapIndexed(transform: (Int, T) -> R): Stream<R> {
return TransformingIndexedStream(this, transform)
}
/**
* Returns a list containing the results of applying the given *transform* function to each element and its index of the original collection
*/
public inline fun <R> String.mapIndexed(transform: (Int, Char) -> R): List<R> {
return mapIndexedTo(ArrayList<R>(), transform)
}
/**
* Appends transformed elements and their indices of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <T, R, C : MutableCollection<in R>> Array<out T>.mapIndexedTo(destination: C, transform: (Int, T) -> R): C {
var index = 0
for (item in this)
destination.add(transform(index++, item))
return destination
}
/**
* Appends transformed elements and their indices of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <R, C : MutableCollection<in R>> BooleanArray.mapIndexedTo(destination: C, transform: (Int, Boolean) -> R): C {
var index = 0
for (item in this)
destination.add(transform(index++, item))
return destination
}
/**
* Appends transformed elements and their indices of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <R, C : MutableCollection<in R>> ByteArray.mapIndexedTo(destination: C, transform: (Int, Byte) -> R): C {
var index = 0
for (item in this)
destination.add(transform(index++, item))
return destination
}
/**
* Appends transformed elements and their indices of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <R, C : MutableCollection<in R>> CharArray.mapIndexedTo(destination: C, transform: (Int, Char) -> R): C {
var index = 0
for (item in this)
destination.add(transform(index++, item))
return destination
}
/**
* Appends transformed elements and their indices of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <R, C : MutableCollection<in R>> DoubleArray.mapIndexedTo(destination: C, transform: (Int, Double) -> R): C {
var index = 0
for (item in this)
destination.add(transform(index++, item))
return destination
}
/**
* Appends transformed elements and their indices of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <R, C : MutableCollection<in R>> FloatArray.mapIndexedTo(destination: C, transform: (Int, Float) -> R): C {
var index = 0
for (item in this)
destination.add(transform(index++, item))
return destination
}
/**
* Appends transformed elements and their indices of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <R, C : MutableCollection<in R>> IntArray.mapIndexedTo(destination: C, transform: (Int, Int) -> R): C {
var index = 0
for (item in this)
destination.add(transform(index++, item))
return destination
}
/**
* Appends transformed elements and their indices of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <R, C : MutableCollection<in R>> LongArray.mapIndexedTo(destination: C, transform: (Int, Long) -> R): C {
var index = 0
for (item in this)
destination.add(transform(index++, item))
return destination
}
/**
* Appends transformed elements and their indices of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <R, C : MutableCollection<in R>> ShortArray.mapIndexedTo(destination: C, transform: (Int, Short) -> R): C {
var index = 0
for (item in this)
destination.add(transform(index++, item))
return destination
}
/**
* Appends transformed elements and their indices of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <T, R, C : MutableCollection<in R>> Iterable<T>.mapIndexedTo(destination: C, transform: (Int, T) -> R): C {
var index = 0
for (item in this)
destination.add(transform(index++, item))
return destination
}
/**
* Appends transformed elements and their indices of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <K, V, R, C : MutableCollection<in R>> Map<K, V>.mapIndexedTo(destination: C, transform: (Int, Map.Entry<K, V>) -> R): C {
var index = 0
for (item in this)
destination.add(transform(index++, item))
return destination
}
/**
* Appends transformed elements and their indices of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <T, R, C : MutableCollection<in R>> Stream<T>.mapIndexedTo(destination: C, transform: (Int, T) -> R): C {
var index = 0
for (item in this)
destination.add(transform(index++, item))
return destination
}
/**
* Appends transformed elements and their indices of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <R, C : MutableCollection<in R>> String.mapIndexedTo(destination: C, transform: (Int, Char) -> R): C {
var index = 0
for (item in this)
destination.add(transform(index++, item))
return destination
}
/**
* Returns a list containing the results of applying the given *transform* function to each non-null element of the original collection
*/
@@ -621,7 +848,7 @@ public inline fun <T : Any, R, C : MutableCollection<in R>> Stream<T?>.mapNotNul
}
/**
* Appends transformed elements of original collection using the given *transform* function
* Appends transformed elements of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <T, R, C : MutableCollection<in R>> Array<out T>.mapTo(destination: C, transform: (T) -> R): C {
@@ -631,7 +858,7 @@ public inline fun <T, R, C : MutableCollection<in R>> Array<out T>.mapTo(destina
}
/**
* Appends transformed elements of original collection using the given *transform* function
* Appends transformed elements of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <R, C : MutableCollection<in R>> BooleanArray.mapTo(destination: C, transform: (Boolean) -> R): C {
@@ -641,7 +868,7 @@ public inline fun <R, C : MutableCollection<in R>> BooleanArray.mapTo(destinatio
}
/**
* Appends transformed elements of original collection using the given *transform* function
* Appends transformed elements of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <R, C : MutableCollection<in R>> ByteArray.mapTo(destination: C, transform: (Byte) -> R): C {
@@ -651,7 +878,7 @@ public inline fun <R, C : MutableCollection<in R>> ByteArray.mapTo(destination:
}
/**
* Appends transformed elements of original collection using the given *transform* function
* Appends transformed elements of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <R, C : MutableCollection<in R>> CharArray.mapTo(destination: C, transform: (Char) -> R): C {
@@ -661,7 +888,7 @@ public inline fun <R, C : MutableCollection<in R>> CharArray.mapTo(destination:
}
/**
* Appends transformed elements of original collection using the given *transform* function
* Appends transformed elements of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <R, C : MutableCollection<in R>> DoubleArray.mapTo(destination: C, transform: (Double) -> R): C {
@@ -671,7 +898,7 @@ public inline fun <R, C : MutableCollection<in R>> DoubleArray.mapTo(destination
}
/**
* Appends transformed elements of original collection using the given *transform* function
* Appends transformed elements of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <R, C : MutableCollection<in R>> FloatArray.mapTo(destination: C, transform: (Float) -> R): C {
@@ -681,7 +908,7 @@ public inline fun <R, C : MutableCollection<in R>> FloatArray.mapTo(destination:
}
/**
* Appends transformed elements of original collection using the given *transform* function
* Appends transformed elements of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <R, C : MutableCollection<in R>> IntArray.mapTo(destination: C, transform: (Int) -> R): C {
@@ -691,7 +918,7 @@ public inline fun <R, C : MutableCollection<in R>> IntArray.mapTo(destination: C
}
/**
* Appends transformed elements of original collection using the given *transform* function
* Appends transformed elements of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <R, C : MutableCollection<in R>> LongArray.mapTo(destination: C, transform: (Long) -> R): C {
@@ -701,7 +928,7 @@ public inline fun <R, C : MutableCollection<in R>> LongArray.mapTo(destination:
}
/**
* Appends transformed elements of original collection using the given *transform* function
* Appends transformed elements of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <R, C : MutableCollection<in R>> ShortArray.mapTo(destination: C, transform: (Short) -> R): C {
@@ -711,7 +938,7 @@ public inline fun <R, C : MutableCollection<in R>> ShortArray.mapTo(destination:
}
/**
* Appends transformed elements of original collection using the given *transform* function
* Appends transformed elements of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <T, R, C : MutableCollection<in R>> Iterable<T>.mapTo(destination: C, transform: (T) -> R): C {
@@ -721,7 +948,7 @@ public inline fun <T, R, C : MutableCollection<in R>> Iterable<T>.mapTo(destinat
}
/**
* Appends transformed elements of original collection using the given *transform* function
* Appends transformed elements of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <K, V, R, C : MutableCollection<in R>> Map<K, V>.mapTo(destination: C, transform: (Map.Entry<K, V>) -> R): C {
@@ -731,7 +958,7 @@ public inline fun <K, V, R, C : MutableCollection<in R>> Map<K, V>.mapTo(destina
}
/**
* Appends transformed elements of original collection using the given *transform* function
* Appends transformed elements of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <T, R, C : MutableCollection<in R>> Stream<T>.mapTo(destination: C, transform: (T) -> R): C {
@@ -741,7 +968,7 @@ public inline fun <T, R, C : MutableCollection<in R>> Stream<T>.mapTo(destinatio
}
/**
* Appends transformed elements of original collection using the given *transform* function
* Appends transformed elements of the original collection using the given *transform* function
* to the given *destination*
*/
public inline fun <R, C : MutableCollection<in R>> String.mapTo(destination: C, transform: (Char) -> R): C {
@@ -65,6 +65,19 @@ public class TransformingStream<T, R>(private val stream: Stream<T>, private val
}
}
public class TransformingIndexedStream<T, R>(private val stream: Stream<T>, private val transformer: (Int, T) -> R) : Stream<R> {
override fun iterator(): Iterator<R> = object : Iterator<R> {
val iterator = stream.iterator()
var index = 0
override fun next(): R {
return transformer(index++, iterator.next())
}
override fun hasNext(): Boolean {
return iterator.hasNext()
}
}
}
public class IndexingStream<T>(private val stream: Stream<T>) : Stream<IndexedValue<T>> {
override fun iterator(): Iterator<IndexedValue<T>> = object : Iterator<IndexedValue<T>> {
val iterator = stream.iterator()
@@ -15,7 +15,7 @@ class IterableWrapper<T>(collection: Iterable<T>) : Iterable<T> {
}
class IterableTest : IterableTests<Iterable<String>>(iterableOf("foo", "bar"), iterableOf<String>())
class SetTest : IterableTests<Set<String>>(hashSetOf("foo", "bar"), hashSetOf<String>())
class SetTest : IterableTests<Set<String>>(setOf("foo", "bar"), setOf<String>())
class ListTest : OrderedIterableTests<List<String>>(listOf("foo", "bar"), listOf<String>())
class ArrayListTest : OrderedIterableTests<ArrayList<String>>(arrayListOf("foo", "bar"), arrayListOf<String>())
@@ -30,6 +30,10 @@ class IteratorsTest {
assertEquals(arrayListOf(0, 3, 3, 6, 9, 15), fibonacci().map { it * 3 }.takeWhile { (i: Int) -> i < 20 }.toList())
}
test fun mapIndexed() {
assertEquals(arrayListOf(0, 1, 2, 6, 12), fibonacci().mapIndexed { index, value -> index * value }.takeWhile {(i: Int) -> i < 20 }.toList())
}
test fun joinConcatenatesTheFirstNElementsAboveAThreshold() {
assertEquals("13, 21, 34, 55, 89, ...", fibonacci().filter { it > 10 }.joinToString(separator = ", ", limit = 5))
}
@@ -44,6 +44,24 @@ fun mapping(): List<GenericFunction> {
}
}
templates add f("mapIndexed(transform: (Int, T) -> R)") {
inline(true)
doc { "Returns a list containing the results of applying the given *transform* function to each element and its index of the original collection" }
typeParam("R")
returns("List<R>")
body {
"return mapIndexedTo(ArrayList<R>(), transform)"
}
inline(false, Streams)
returns(Streams) { "Stream<R>" }
doc(Streams) { "Returns a stream containing the results of applying the given *transform* function to each element and its index of the original stream" }
body(Streams) {
"return TransformingIndexedStream(this, transform)"
}
}
templates add f("map(transform: (T) -> R)") {
inline(true)
@@ -92,7 +110,7 @@ fun mapping(): List<GenericFunction> {
doc {
"""
Appends transformed elements of original collection using the given *transform* function
Appends transformed elements of the original collection using the given *transform* function
to the given *destination*
"""
}
@@ -110,6 +128,30 @@ fun mapping(): List<GenericFunction> {
include(Maps)
}
templates add f("mapIndexedTo(destination: C, transform: (Int, T) -> R)") {
inline(true)
doc {
"""
Appends transformed elements and their indices of the original collection using the given *transform* function
to the given *destination*
"""
}
typeParam("R")
typeParam("C : MutableCollection<in R>")
returns("C")
body {
"""
var index = 0
for (item in this)
destination.add(transform(index++, item))
return destination
"""
}
include(Maps)
}
templates add f("mapNotNullTo(destination: C, transform: (T) -> R)") {
inline(true)
exclude(Strings, ArraysOfPrimitives)