Skip to content

Commit 4afa823

Browse files
committed
generalize toListImpl to support conversions into lists and sequences
The previous implementation already was based on iterating over rows, with this generalization, the user can now decide whether to eagerly convert a dataframe into a list, or use lazy transformations via a sequence.
1 parent bddf7bf commit 4afa823

File tree

8 files changed

+56
-17
lines changed

8 files changed

+56
-17
lines changed

core/api/core.api

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9808,8 +9808,8 @@ public final class org/jetbrains/kotlinx/dataframe/impl/api/ToDataFrameKt {
98089808
public static final fun createDataFrameImpl (Ljava/lang/Iterable;Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
98099809
}
98109810

9811-
public final class org/jetbrains/kotlinx/dataframe/impl/api/ToListKt {
9812-
public static final fun toListImpl (Lorg/jetbrains/kotlinx/dataframe/DataFrame;Lkotlin/reflect/KType;)Ljava/util/List;
9811+
public final class org/jetbrains/kotlinx/dataframe/impl/api/ToSequenceKt {
9812+
public static final fun toSequenceImpl (Lorg/jetbrains/kotlinx/dataframe/DataFrame;Lkotlin/reflect/KType;)Ljava/lang/Iterable;
98139813
}
98149814

98159815
public final class org/jetbrains/kotlinx/dataframe/impl/api/UpdateKt {

core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/toList.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ package org.jetbrains.kotlinx.dataframe.api
22

33
import org.jetbrains.kotlinx.dataframe.AnyFrame
44
import org.jetbrains.kotlinx.dataframe.DataFrame
5-
import org.jetbrains.kotlinx.dataframe.impl.api.toListImpl
5+
import org.jetbrains.kotlinx.dataframe.impl.api.toSequenceImpl
66
import kotlin.reflect.typeOf
77

88
// region DataFrame
99

10-
public inline fun <reified T> DataFrame<T>.toList(): List<T> = toListImpl(typeOf<T>()) as List<T>
10+
public inline fun <reified T> DataFrame<T>.toList(): List<T> = toSequenceImpl(typeOf<T>()).toList() as List<T>
1111

12-
public inline fun <reified T> AnyFrame.toListOf(): List<T> = toListImpl(typeOf<T>()) as List<T>
12+
public inline fun <reified T> AnyFrame.toListOf(): List<T> = toSequenceImpl(typeOf<T>()).toList() as List<T>
1313

1414
// endregion
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.jetbrains.kotlinx.dataframe.api
2+
3+
import org.jetbrains.kotlinx.dataframe.AnyFrame
4+
import org.jetbrains.kotlinx.dataframe.DataFrame
5+
import org.jetbrains.kotlinx.dataframe.impl.api.toSequenceImpl
6+
import kotlin.reflect.typeOf
7+
8+
// region DataFrame
9+
10+
public inline fun <reified T> DataFrame<T>.toSequence(): Sequence<T> = toSequenceImpl(typeOf<T>()) as Sequence<T>
11+
12+
public inline fun <reified T> AnyFrame.toSequenceOf(): Sequence<T> = toSequenceImpl(typeOf<T>()) as Sequence<T>
13+
14+
// endregion

core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/toList.kt renamed to core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/toSequence.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import kotlin.reflect.full.withNullability
2121
import kotlin.reflect.jvm.jvmErasure
2222

2323
@PublishedApi
24-
internal fun AnyFrame.toListImpl(type: KType): List<Any> {
24+
internal fun AnyFrame.toSequenceImpl(type: KType): Sequence<Any> {
2525
val clazz = type.jvmErasure
2626
require(clazz.isData) { "`$clazz` is not a data class. `toList` is supported only for data classes." }
2727

@@ -46,15 +46,15 @@ internal fun AnyFrame.toListImpl(type: KType): List<Any> {
4646
val col: AnyCol = if (it.type.jvmErasure == List::class) {
4747
val elementType = it.type.arguments[0].type
4848
require(elementType != null) { "FrameColumn can not be converted to type `List<*>`" }
49-
column.asAnyFrameColumn().map { it.toListImpl(elementType) }
49+
column.asAnyFrameColumn().map { it.toSequenceImpl(elementType).toList() }
5050
} else {
5151
error("FrameColumn can not be converted to type `${it.type}`")
5252
}
5353
col
5454
}
5555

5656
ColumnKind.Group -> {
57-
DataColumn.createValueColumn(column.name(), column.asColumnGroup().toListImpl(it.type))
57+
DataColumn.createValueColumn(column.name(), column.asColumnGroup().toSequenceImpl(it.type).toList())
5858
}
5959

6060
ColumnKind.Value -> {
@@ -74,7 +74,7 @@ internal fun AnyFrame.toListImpl(type: KType): List<Any> {
7474
convertedColumn
7575
}
7676

77-
return rows().map { row ->
77+
return rows().asSequence().map { row ->
7878
val parameters = convertedColumns
7979
.map { row[it] }
8080
.toTypedArray()

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/toList.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ package org.jetbrains.kotlinx.dataframe.api
22

33
import org.jetbrains.kotlinx.dataframe.AnyFrame
44
import org.jetbrains.kotlinx.dataframe.DataFrame
5-
import org.jetbrains.kotlinx.dataframe.impl.api.toListImpl
5+
import org.jetbrains.kotlinx.dataframe.impl.api.toSequenceImpl
66
import kotlin.reflect.typeOf
77

88
// region DataFrame
99

10-
public inline fun <reified T> DataFrame<T>.toList(): List<T> = toListImpl(typeOf<T>()) as List<T>
10+
public inline fun <reified T> DataFrame<T>.toList(): List<T> = toSequenceImpl(typeOf<T>()).toList() as List<T>
1111

12-
public inline fun <reified T> AnyFrame.toListOf(): List<T> = toListImpl(typeOf<T>()) as List<T>
12+
public inline fun <reified T> AnyFrame.toListOf(): List<T> = toSequenceImpl(typeOf<T>()).toList() as List<T>
1313

1414
// endregion
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.jetbrains.kotlinx.dataframe.api
2+
3+
import org.jetbrains.kotlinx.dataframe.AnyFrame
4+
import org.jetbrains.kotlinx.dataframe.DataFrame
5+
import org.jetbrains.kotlinx.dataframe.impl.api.toSequenceImpl
6+
import kotlin.reflect.typeOf
7+
8+
// region DataFrame
9+
10+
public inline fun <reified T> DataFrame<T>.toSequence(): Sequence<T> = toSequenceImpl(typeOf<T>()) as Sequence<T>
11+
12+
public inline fun <reified T> AnyFrame.toSequenceOf(): Sequence<T> = toSequenceImpl(typeOf<T>()) as Sequence<T>
13+
14+
// endregion

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/toList.kt renamed to core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/toSequence.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import kotlin.reflect.full.withNullability
2121
import kotlin.reflect.jvm.jvmErasure
2222

2323
@PublishedApi
24-
internal fun AnyFrame.toListImpl(type: KType): List<Any> {
24+
internal fun AnyFrame.toSequenceImpl(type: KType): Sequence<Any> {
2525
val clazz = type.jvmErasure
2626
require(clazz.isData) { "`$clazz` is not a data class. `toList` is supported only for data classes." }
2727

@@ -46,15 +46,15 @@ internal fun AnyFrame.toListImpl(type: KType): List<Any> {
4646
val col: AnyCol = if (it.type.jvmErasure == List::class) {
4747
val elementType = it.type.arguments[0].type
4848
require(elementType != null) { "FrameColumn can not be converted to type `List<*>`" }
49-
column.asAnyFrameColumn().map { it.toListImpl(elementType) }
49+
column.asAnyFrameColumn().map { it.toSequenceImpl(elementType).toList() }
5050
} else {
5151
error("FrameColumn can not be converted to type `${it.type}`")
5252
}
5353
col
5454
}
5555

5656
ColumnKind.Group -> {
57-
DataColumn.createValueColumn(column.name(), column.asColumnGroup().toListImpl(it.type))
57+
DataColumn.createValueColumn(column.name(), column.asColumnGroup().toSequenceImpl(it.type).toList())
5858
}
5959

6060
ColumnKind.Value -> {
@@ -74,7 +74,7 @@ internal fun AnyFrame.toListImpl(type: KType): List<Any> {
7474
convertedColumn
7575
}
7676

77-
return rows().map { row ->
77+
return rows().asSequence().map { row ->
7878
val parameters = convertedColumns
7979
.map { row[it] }
8080
.toTypedArray()

docs/StardustDocs/topics/collectionsInterop.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ for Gradle or the [Kotlin Jupyter kernel](gettingStartedJupyterNotebook.md)
8282

8383
</tip>
8484

85-
After your data is transformed, [`DataFrame`](DataFrame.md) instances can be exported
85+
After your data is transformed, [`DataFrame`](DataFrame.md) instances can be exported eagerly
8686
into [`List`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/) of another data class using [toList](toList.md) or [toListOf](toList.md#tolistof) extensions:
8787

8888
<!---FUN listInterop4-->
@@ -93,6 +93,17 @@ data class Output(val a: Int, val b: Int, val c: Int)
9393
val result = df2.toListOf<Output>()
9494
```
9595

96+
Alternatively, one can create lazy [`Sequence`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-sequence/) objects.
97+
This avoids holding the entire list of objects in memory as objects are created on the fly as needed.
98+
99+
<!---FUN listInterop5-->
100+
101+
```kotlin
102+
data class Output(val a: Int, val b: Int, val c: Int)
103+
104+
val result = df2.toSequenceOf<Output>()
105+
```
106+
96107
<!---END-->
97108

98109
### Converting columns with object instances to ColumnGroup

0 commit comments

Comments
 (0)