Introduce 'pairwise' function, KEEP-11

This commit is contained in:
Ilya Gorbunov
2017-04-26 23:49:11 +03:00
parent b73be50e5b
commit c815ccfd6a
15 changed files with 298 additions and 1 deletions
@@ -116,6 +116,25 @@ abstract class OrderedIterableTests<T : Iterable<String>>(createFrom: (Array<out
expect(null) { empty.lastOrNull() }
expect("foo") { data.lastOrNull { it.startsWith("f") } }
}
@Test
fun pairwise() {
val data = createFrom("", "a", "xyz")
val lengthDeltas = data.pairwise { a, b -> b.length - a.length }
assertEquals(listOf(1, 2), lengthDeltas)
assertTrue(empty.pairwise { a, b -> a + b }.isEmpty())
assertTrue(createFrom("foo").pairwise { a, b -> a + b }.isEmpty())
}
@Test
fun pairwisePairs() {
assertTrue(empty.pairwise().isEmpty())
assertTrue(createFrom("foo").pairwise().isEmpty())
assertEquals(listOf("a" to "b"), createFrom("a", "b").pairwise())
assertEquals(listOf("a" to "b", "b" to "c"), createFrom("a", "b", "c").pairwise())
}
}
abstract class IterableTests<T : Iterable<String>>(val createFrom: (Array<out String>) -> T, val empty: T) {
@@ -1,3 +1,19 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package test.collections
import org.junit.Test
@@ -12,6 +28,22 @@ fun fibonacci(): Sequence<Int> {
public class SequenceTest {
private class TriggerSequence<out T>(val source: Sequence<T>) : Sequence<T> {
var iterated: Boolean = false
private set
override fun iterator(): Iterator<T> = source.iterator().also { iterated = true }
}
fun <T> ensureIsIntermediate(source: Sequence<T>, operation: (Sequence<T>) -> Sequence<*>) {
TriggerSequence(source).let { s ->
val result = operation(s)
assertFalse(s.iterated, "Source should not be iterated before the result is")
result.iterator().hasNext()
assertTrue(s.iterated, "Source should be iterated after the result is iterated")
}
}
@Test fun filterEmptySequence() {
for (sequence in listOf(emptySequence<String>(), sequenceOf<String>())) {
assertEquals(0, sequence.filter { false }.count())
@@ -165,6 +197,25 @@ public class SequenceTest {
assertEquals("", sequenceOf(1).dropWhile { it < 200 }.joinToString(limit = 10))
}
@Test fun pairwise() {
val deltas = fibonacci().pairwise { a, b -> b - a }
// deltas of 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, ...
// is the same sequence prepended by 1
assertEquals(listOf(1) + fibonacci().take(9), deltas.take(10).toList())
ensureIsIntermediate(source = sequenceOf(1, 2)) { it.pairwise { a, b -> b - a } }
}
@Test fun pairwisePairs() {
val pairs: Sequence<Pair<String, String>> = sequenceOf("a", "b", "c", "d").pairwise()
assertEquals(listOf("a" to "b", "b" to "c", "c" to "d"), pairs.toList())
assertTrue(emptySequence<String>().pairwise().toList().isEmpty())
assertTrue(sequenceOf(1).pairwise().toList().isEmpty())
ensureIsIntermediate(source = sequenceOf(1, 2)) { it.pairwise() }
}
@Test fun zip() {
expect(listOf("ab", "bc", "cd")) {
sequenceOf("a", "b", "c").zip(sequenceOf("b", "c", "d")) { a, b -> a + b }.toList()
+13 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -837,6 +837,18 @@ class StringTest {
assertContentEquals("abc", pair.second, "pair.second")
}
@Test fun pairwise() = withOneCharSequenceArg { arg1 ->
assertEquals(listOf("ab", "bc"), arg1("abc").pairwise { a, b -> a.toString() + b })
assertTrue(arg1("").pairwise { a, b -> a.toString() + b }.isEmpty())
assertTrue(arg1("a").pairwise { a, b -> a.toString() + b }.isEmpty())
}
@Test fun pairwisePairs() = withOneCharSequenceArg { arg1 ->
assertEquals(listOf('a' to 'b', 'b' to 'c'), arg1("abc").pairwise())
assertTrue(arg1("").pairwise().isEmpty())
assertTrue(arg1("a").pairwise().isEmpty())
}
@Test fun map() = withOneCharSequenceArg { arg1 ->
assertEquals(listOf('a', 'b', 'c'), arg1("abc").map { it })