From aae196839ef5673cec0886d779d744c4de995aae Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 23 Mar 2012 16:17:32 +0100 Subject: [PATCH] Reverting the pull-request #29 due to the upcoming redesign of the lazy collections API --- libraries/stdlib/src/sequences/Sequence.kt | 105 ------------------ libraries/stdlib/src/sequences/Sequences.kt | 74 ------------ .../stdlib/test/sequences/SequenceTest.kt | 83 -------------- .../stdlib/test/sequences/SequencesTest.kt | 68 ------------ 4 files changed, 330 deletions(-) delete mode 100644 libraries/stdlib/src/sequences/Sequence.kt delete mode 100644 libraries/stdlib/src/sequences/Sequences.kt delete mode 100644 libraries/stdlib/test/sequences/SequenceTest.kt delete mode 100644 libraries/stdlib/test/sequences/SequencesTest.kt diff --git a/libraries/stdlib/src/sequences/Sequence.kt b/libraries/stdlib/src/sequences/Sequence.kt deleted file mode 100644 index ce85477097e..00000000000 --- a/libraries/stdlib/src/sequences/Sequence.kt +++ /dev/null @@ -1,105 +0,0 @@ -package kotlin.sequences - -/** - * A sequence of items of type *T* that are lazily produced by the given closure - * - * @param next a closure yielding the next element in this sequence - * - * @author [Franck Rasolo](http://www.linkedin.com/in/franckrasolo) - * @since 1.0 - */ -class Sequence(val next: () -> T?) : Iterable { - - override fun iterator(): Iterator = YieldingIterator { (next)() } - - /** - * Retains only elements that satisfy the given predicate - * - * @param predicate the predicate evaluated against objects of type *T* - */ - fun filter(predicate: (T) -> Boolean): Sequence { - val iterator = iterator() - - fun next(): T? { - while (iterator.hasNext) { - val item = iterator.next() - if ((predicate)(item)) return item - } - return null - } - - return Sequence { next() } - } - - /** - * Reduces this sequence using the binary operator, from left to right. - * Only finite sequences can be reduced. - * - * @param seed an initial value, typically the left-identity of the operator - * @param operator a binary operator - */ - fun fold(seed: T, operator: (T, T) -> T): T { - var result = seed - for (item in this) result = (operator)(result, item) - return result - } - - /** - * Produces a sequence obtained by applying *transform* to each element of this sequence - * - * @param transform the function transforming an object of type *T* into an object of type *R* - */ - fun map(transform: (T) -> R): Sequence { - val iterator = iterator() - fun next(): R? = if (iterator.hasNext) (transform)(iterator.next()) else null - return Sequence { next() } - } - - /** - * Extracts the prefix of this sequence as a finite sequence of length *n* - * - * @param n the number of elements of the extracted sequence - */ - fun take(n: Int): Sequence { - fun countTo(n: Int): (T) -> Boolean { - var count = 0 - return { ++count; count <= n } - } - return takeWhile(countTo(n)) - } - - /** - * Extracts the longest prefix, possibly empty, of this sequence where each element satisfies *predicate* - * - * @param predicate the predicate evaluated against objects of type *T* - */ - fun takeWhile(predicate: (T) -> Boolean): Sequence { - val iterator = iterator() - - fun next(): T? { - if (iterator.hasNext) { - val item = iterator.next() - if ((predicate)(item)) return item - } - return null - } - - return Sequence { next() } - } -} - -private class YieldingIterator(val yield: () -> T?) : Iterator { - var current : T? = (yield)() - - override val hasNext: Boolean - get() = current != null - - override fun next(): T { - val next = current - if (next != null) { - current = (yield)() - return next - } - throw java.util.NoSuchElementException() - } -} diff --git a/libraries/stdlib/src/sequences/Sequences.kt b/libraries/stdlib/src/sequences/Sequences.kt deleted file mode 100644 index 002c5f0a10e..00000000000 --- a/libraries/stdlib/src/sequences/Sequences.kt +++ /dev/null @@ -1,74 +0,0 @@ -package kotlin.sequences - -/** Creates a sequence from the given list of *elements* */ -inline fun sequence(vararg elements: T): Sequence = asSequence(elements.iterator()) - -/** Creates a sequence of elements lazily obtained from this Kotlin [[jet.Iterable]] */ -inline fun Iterable.asSequence(): Sequence = asSequence(iterator()) - -/** Creates a sequence of elements lazily obtained from this Java [[java.lang.Iterable]] */ -inline fun java.lang.Iterable.asSequence(): Sequence = asSequence(iterator().sure() as java.util.Iterator) - -private fun asSequence(iterator: Iterator) = Sequence { if (iterator.hasNext) iterator.next() else null } -private fun asSequence(iterator: java.util.Iterator) = Sequence { if (iterator.hasNext()) iterator.next() else null } - -/** - * Produces the [cartesian product](http://en.wikipedia.org/wiki/Cartesian_product#n-ary_product) as a sequence of ordered pairs of elements lazily obtained - * from two [[Iterable]] instances - */ -fun Iterable.times(other: Iterable): Sequence<#(T, T)> { - val first = iterator(); var second = other.iterator(); var a: T? = null - - fun nextPair(): #(T, T)? { - if (a == null && first.hasNext) a = first.next() - if (second.hasNext) return #(a.sure(), second.next()) - if (first.hasNext) { - a = first.next(); second = other.iterator() - return #(a.sure(), second.next()) - } - return null - } - - return Sequence<#(T, T)> { nextPair() } -} - -/** - * Partitions this string into groups of fixed size strings - * - * @param size the number of characters per group - * - * @return a sequence of strings of size *size*, except the last will be truncated if the elements do not divide evenly - */ -fun String.grouped(size: Int, iterator: CharIterator = iterator()): Sequence { - fun nextGroup(): String? { - if (iterator.hasNext) { - val window = StringBuilder() - for (i in 1..size) if (iterator.hasNext) window.append(iterator.next()) - return window.toString() - } - return null - } - - return Sequence { nextGroup() } -} - -/** - * Groups elements in fixed size blocks by passing a *sliding window* over them, as opposed to partitioning them, as is done in `String.grouped` - * - * @param size the number of characters per group - * - * @return a sequence of strings of size *size*, except the last and the only element will be truncated if there are fewer characters than *size* - */ -fun String.sliding(size: Int, iterator: CharIterator = iterator()): Sequence { - val window = StringBuilder() - - fun nextWindow(): String? { - if (window.length() == 0) { - for (i in 1..size) if (iterator.hasNext) window.append(iterator.next()) - return window.toString() - } - return if (iterator.hasNext) window.deleteCharAt(0)?.append(iterator.next()).toString() else null - } - - return Sequence { nextWindow() } -} diff --git a/libraries/stdlib/test/sequences/SequenceTest.kt b/libraries/stdlib/test/sequences/SequenceTest.kt deleted file mode 100644 index 9a02bd86b47..00000000000 --- a/libraries/stdlib/test/sequences/SequenceTest.kt +++ /dev/null @@ -1,83 +0,0 @@ -package test.sequences - -import java.util.ArrayList - -import kotlin.sequences.asSequence -import kotlin.sequences.sequence -import kotlin.util.arrayList -import kotlin.util.fold - -import kotlin.test.assertEquals -import org.junit.Test - -class SequenceTest { - - Test fun filterReturnsTheExpectedSequence() { - val actual = (1..10).asSequence().filter { it % 2 == 0 } - assertEquals(arrayList(2, 4, 6, 8, 10), actual.toList()) - } - - Test fun filterReturnsAnEmptySequenceWhenNoElementMatchesThePredicate() { - val actual = sequence(1, 3, 4, 7).filter { it > 7 } - assertEquals(ArrayList(), actual.toList()) - } - - Test fun foldReturnsTheExpectedReduction() { - val actual = (1..10).asSequence().filter { it % 2 == 1 }.fold(0, sum) - assertEquals(1 + 3 + 5 + 7 + 9, actual) - } - - Test fun foldReturnsTheInitialValueForAnEmptySequence() { - val initialValue = 0 - val actual = (1..0).asSequence().fold(initialValue, sum) - - assertEquals(initialValue, actual) - } - - private val sum = { (a : Int, b : Int) -> a + b } - - Test fun mapReturnsTheExpectedTransformation() { - val actual = sequence(1, 3, 4, 7).map { it * 2 } - assertEquals(arrayList(2, 6, 8, 14), actual.toList()) - } - - Test fun takeReturnsTheFirstNElements() { - var actual = (1..5).asSequence().take(3) - assertEquals(arrayList(1, 2, 3), actual.toList()) - } - - Test fun takeReturnsTheEntireSequenceWhenTheNumberOfElementsIsGreaterThanItsSize() { - val actual = sequence(1, 2).take(3) - assertEquals(arrayList(1, 2), actual.toList()) - } - - Test fun takeReturnsAnEmptySequenceForAnEmptySequence() { - val actual = (1..0).asSequence().take(3) - assertEquals(ArrayList(), actual.toList()) - } - - Test fun takeReturnsAnEmptySequenceWhenTheNumberOfElementsToExtractIsZero() { - val actual = sequence(1, 2).take(0) - assertEquals(ArrayList(), actual.toList()) - } - - Test fun takeReturnsAnEmptySequenceWhenTheNumberOfElementsToExtractIsNegative() { - val actual = sequence(1, 2).take(-1) - assertEquals(ArrayList(), actual.toList()) - } - - Test fun takeWhileReturnsTheFirstElementsMatchingAGivenPredicate() { - val actual = sequence(1, 2, 3, 4, 1, 2, 3, 4).takeWhile { it < 3 } - assertEquals(arrayList(1, 2), actual.toList()) - } - - Test fun takeWhileReturnsTheEntireSequenceWhenThePredicateMatchesAllElements() { - val actual = sequence(1, 2, 3).takeWhile { it < 9 } - assertEquals(arrayList(1, 2, 3), actual.toList()) - } - - Test fun takeWhileReturnsAnEmptySequenceWhenThePredicateMatchesNothing() { - val actual = sequence(1, 2, 3).takeWhile { it < 0 } - assertEquals(ArrayList(), actual.toList()) - } -} diff --git a/libraries/stdlib/test/sequences/SequencesTest.kt b/libraries/stdlib/test/sequences/SequencesTest.kt deleted file mode 100644 index 8df18129815..00000000000 --- a/libraries/stdlib/test/sequences/SequencesTest.kt +++ /dev/null @@ -1,68 +0,0 @@ -package test.sequences - -import kotlin.sequences.grouped -import kotlin.sequences.sequence -import kotlin.sequences.sliding -import kotlin.sequences.times -import kotlin.util.arrayList - -import kotlin.test.assertEquals -import org.junit.Test - -class SequencesTest { - - Test fun timesComputesTheCartesianSquareOfAnIterable() { - val actual = (1..3) * (1..3) - val expected = arrayList( - #(1, 1), #(1, 2), #(1, 3), - #(2, 1), #(2, 2), #(2, 3), - #(3, 1), #(3, 2), #(3, 3) - ) - assertEquals(expected, actual.toList()) - } - - Test fun timesComputesTheCartesianProductOfTwoRanges() { - val actual = (1..3) * (4..7) - val expected = arrayList( - #(1, 4), #(1, 5), #(1, 6), #(1, 7), - #(2, 4), #(2, 5), #(2, 6), #(2, 7), - #(3, 4), #(3, 5), #(3, 6), #(3, 7) - ) - assertEquals(expected, actual.toList()) - } - - Test fun timesComputesTheCartesianProductOfTwoIterables() { - val actual = sequence(1, 3, 5, 7) * (4..6) - val expected = arrayList( - #(1, 4), #(1, 5), #(1, 6), - #(3, 4), #(3, 5), #(3, 6), - #(5, 4), #(5, 5), #(5, 6), - #(7, 4), #(7, 5), #(7, 6) - ) - assertEquals(expected, actual.toList()) - } - - Test fun groupedReturnsFixedSizeGroupsOfStrings() { - val digits = """ -62229893423380308135336276614282806444486645238749 -30358907296290491560440772390713810515859307960866 -70172427121883998797908792274921901699720888093776 -65727333001053367881220235421809751254540594752243 -""".trim().replaceAll("\\n", "") - - val actual = digits.grouped(50).toList().get(2) - assertEquals("70172427121883998797908792274921901699720888093776", actual) - } - - Test fun slidingOverALongStringOfDigits() { - val digits = """ -62229893423380308135336276614282806444486645238749 -30358907296290491560440772390713810515859307960866 -70172427121883998797908792274921901699720888093776 -65727333001053367881220235421809751254540594752243 -""".trim().replaceAll("\\n", "") - - val actual = digits.sliding(3).filter { Integer.parseInt(it) > 990 } - assertEquals(arrayList("998", "997"), actual.toList()) - } -}