Skip to content

Commit a467b44

Browse files
committed
Rename colsRange into select in ColumnsSelectionDsl. Fix bug with nested select in replace{}.with {}. Remove host and parent from ColumnWithPath. Add parentName into ColumnWithPath and ColumnPath`.
1 parent 4bbe272 commit a467b44

26 files changed

+113
-113
lines changed

src/main/kotlin/org/jetbrains/kotlinx/dataframe/DataColumn.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import org.jetbrains.kotlinx.dataframe.columns.ColumnResolutionContext
1515
import org.jetbrains.kotlinx.dataframe.columns.ColumnWithPath
1616
import org.jetbrains.kotlinx.dataframe.columns.FrameColumn
1717
import org.jetbrains.kotlinx.dataframe.columns.ValueColumn
18-
import org.jetbrains.kotlinx.dataframe.columns.size
1918
import org.jetbrains.kotlinx.dataframe.impl.columns.ColumnGroupImpl
2019
import org.jetbrains.kotlinx.dataframe.impl.columns.FrameColumnImpl
2120
import org.jetbrains.kotlinx.dataframe.impl.columns.ValueColumnImpl
@@ -115,7 +114,7 @@ public interface DataColumn<out T> : BaseColumn<T> {
115114

116115
override fun rename(newName: String): DataColumn<T>
117116

118-
override fun resolveSingle(context: ColumnResolutionContext): ColumnWithPath<T>? = this.addPath(context.df)
117+
override fun resolveSingle(context: ColumnResolutionContext): ColumnWithPath<T>? = this.addPath()
119118

120119
override operator fun getValue(thisRef: Any?, property: KProperty<*>): DataColumn<T> = super.getValue(thisRef, property) as DataColumn<T>
121120

src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/ColumnsSelectionDsl.kt

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,18 @@ import org.jetbrains.kotlinx.dataframe.columns.ColumnAccessor
1010
import org.jetbrains.kotlinx.dataframe.columns.ColumnGroup
1111
import org.jetbrains.kotlinx.dataframe.columns.ColumnPath
1212
import org.jetbrains.kotlinx.dataframe.columns.ColumnReference
13+
import org.jetbrains.kotlinx.dataframe.columns.ColumnResolutionContext
1314
import org.jetbrains.kotlinx.dataframe.columns.ColumnSet
1415
import org.jetbrains.kotlinx.dataframe.columns.ColumnWithPath
1516
import org.jetbrains.kotlinx.dataframe.columns.FrameColumn
1617
import org.jetbrains.kotlinx.dataframe.columns.SingleColumn
17-
import org.jetbrains.kotlinx.dataframe.columns.UnresolvedColumnsPolicy
1818
import org.jetbrains.kotlinx.dataframe.columns.renamedReference
19-
import org.jetbrains.kotlinx.dataframe.impl.DataFrameReceiver
2019
import org.jetbrains.kotlinx.dataframe.impl.columnName
2120
import org.jetbrains.kotlinx.dataframe.impl.columns.ColumnsList
2221
import org.jetbrains.kotlinx.dataframe.impl.columns.DistinctColumnSet
22+
import org.jetbrains.kotlinx.dataframe.impl.columns.addPath
2323
import org.jetbrains.kotlinx.dataframe.impl.columns.allColumnsExcept
24+
import org.jetbrains.kotlinx.dataframe.impl.columns.changePath
2425
import org.jetbrains.kotlinx.dataframe.impl.columns.createColumnSet
2526
import org.jetbrains.kotlinx.dataframe.impl.columns.getAt
2627
import org.jetbrains.kotlinx.dataframe.impl.columns.getChildrenAt
@@ -30,6 +31,7 @@ import org.jetbrains.kotlinx.dataframe.impl.columns.top
3031
import org.jetbrains.kotlinx.dataframe.impl.columns.transform
3132
import org.jetbrains.kotlinx.dataframe.impl.columns.transformSingle
3233
import org.jetbrains.kotlinx.dataframe.impl.columns.tree.dfs
34+
import org.jetbrains.kotlinx.dataframe.impl.getColumnsWithPaths
3335
import kotlin.reflect.KProperty
3436
import kotlin.reflect.KType
3537
import kotlin.reflect.typeOf
@@ -63,13 +65,23 @@ public interface ColumnsSelectionDsl<out T> : ColumnSelectionDsl<T>, SingleColum
6365

6466
public fun ColumnsContainer<*>.group(name: String): ColumnGroupReference = name.toColumnOf()
6567

66-
public operator fun String.rangeTo(endInclusive: String): ColumnSet<*> = colsRange(this, endInclusive)
67-
68-
public operator fun Column.rangeTo(endInclusive: Column): ColumnSet<*> {
69-
val parent = path().parent()
70-
require(parent != null)
71-
require(endInclusive.path().parent() == parent) { "Start and end columns have different parent column paths" }
72-
return parent.colsRange(name, endInclusive.name)
68+
public operator fun String.rangeTo(endInclusive: String): ColumnSet<*> = toColumnAccessor().rangeTo(endInclusive.toColumnAccessor())
69+
70+
public operator fun Column.rangeTo(endInclusive: Column): ColumnSet<*> = object : ColumnSet<Any?> {
71+
override fun resolve(context: ColumnResolutionContext): List<ColumnWithPath<Any?>> {
72+
val startPath = this@rangeTo.resolveSingle(context)!!.path
73+
val endPath = endInclusive.resolveSingle(context)!!.path
74+
val parentPath = startPath.parent()!!
75+
require(parentPath == endPath.parent()) { "Start and end columns have different parent column paths" }
76+
val parentCol = context.df.getColumnGroup(parentPath)
77+
val startIndex = parentCol.getColumnIndex(startPath.name)
78+
val endIndex = parentCol.getColumnIndex(endPath.name)
79+
return (startIndex..endIndex).map {
80+
parentCol.getColumn(it).let {
81+
it.addPath(parentPath + it.name)
82+
}
83+
}
84+
}
7385
}
7486

7587
public fun none(): ColumnSet<*> = ColumnsList<Any?>(emptyList())
@@ -94,24 +106,16 @@ public interface ColumnsSelectionDsl<out T> : ColumnSelectionDsl<T>, SingleColum
94106
public fun ColumnSet<*>.cols(range: IntRange): ColumnSet<Any?> =
95107
transform { it.flatMap { it.children().subList(range.start, range.endInclusive + 1) } }
96108

97-
// region colsRange
109+
// region select
98110

99-
public fun <C, R> ColumnGroup<C>.colsRange(selector: ColumnsSelector<C, R>): ColumnSet<R> {
100-
val receiver = object : DataFrameReceiver<C>(this, UnresolvedColumnsPolicy.Fail), ColumnsSelectionDsl<C> { }
101-
return selector(receiver, receiver)
102-
}
111+
public fun <C> ColumnSet<DataRow<C>>.select(vararg columns: String): ColumnSet<*> = select { columns.toColumns() }
112+
113+
public fun <C, R> ColumnSet<DataRow<C>>.select(vararg columns: KProperty<R>): ColumnSet<R> = select { columns.toColumns() }
103114

104-
public fun ColumnSet<*>.colsRange(start: String, endInclusive: String): ColumnSet<Any?> {
105-
val set = this
106-
return set.transform {
107-
it.flatMap {
108-
val children = it.children()
109-
val startIndex = children.indexOfFirst { it.name == start }
110-
require(startIndex >= 0) { "Column `$start` not found" }
111-
val endIndex = children.indexOfLast { it.name == endInclusive }
112-
require(endIndex >= 0) { "Column `$endInclusive` not found" }
113-
require(endIndex >= startIndex) { "End column `$endInclusive` is before start column `$start`" }
114-
children.subList(startIndex, endIndex + 1)
115+
public fun <C, R> ColumnSet<DataRow<C>>.select(selector: ColumnsSelector<C, R>): ColumnSet<R> = createColumnSet {
116+
this@select.resolve(it).flatMap { group ->
117+
group.asColumnGroup().getColumnsWithPaths(selector).map {
118+
it.changePath(group.path + it.path)
115119
}
116120
}
117121
}

src/main/kotlin/org/jetbrains/kotlinx/dataframe/columns/ColumnPath.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ public data class ColumnPath(val path: List<String>) : List<String> by path, Col
3939

4040
override fun name(): String = path.last()
4141

42+
val columnName: String get() = name()
43+
44+
val parentName: String? get() = if (path.size > 1) path[path.size - 2] else null
45+
4246
override fun rename(newName: String): ColumnPath = ColumnPath(path.dropLast(1) + newName)
4347

4448
override fun getValue(row: AnyRow): Any? = row.owner[this][row.index()]

src/main/kotlin/org/jetbrains/kotlinx/dataframe/columns/ColumnReference.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public interface ColumnReference<out C> : SingleColumn<C> {
3434
public fun getValueOrNull(row: AnyRow): C? = resolveFor(row.df())?.get(row.index())
3535

3636
override fun resolveSingle(context: ColumnResolutionContext): ColumnWithPath<C>? {
37-
return context.df.getColumn<C>(path(), context.unresolvedColumnsPolicy)?.addPath(path(), context.df)
37+
return context.df.getColumn<C>(path(), context.unresolvedColumnsPolicy)?.addPath(path())
3838
}
3939
}
4040

src/main/kotlin/org/jetbrains/kotlinx/dataframe/columns/ColumnWithPath.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.jetbrains.kotlinx.dataframe.columns
22

3-
import org.jetbrains.kotlinx.dataframe.ColumnsContainer
43
import org.jetbrains.kotlinx.dataframe.DataColumn
54
import org.jetbrains.kotlinx.dataframe.api.asColumnGroup
65
import org.jetbrains.kotlinx.dataframe.api.isColumnGroup
@@ -10,15 +9,15 @@ import org.jetbrains.kotlinx.dataframe.impl.columns.depth
109

1110
public interface ColumnWithPath<out T> : DataColumn<T> {
1211

13-
public val host: ColumnsContainer<*>
1412
public val data: DataColumn<T>
1513
public val path: ColumnPath
16-
public val parent: ColumnWithPath<*>?
14+
public val name: String get() = name()
15+
public val parentName: String? get() = path.parentName
1716
public fun depth(): Int = path.depth()
18-
public fun <C> getChild(accessor: ColumnReference<C>): ColumnWithPath<C>? = asColumnGroup().getColumnOrNull(accessor)?.addPath(path + accessor.path(), host)
19-
public fun getChild(name: String): ColumnWithPath<Any?>? = asColumnGroup().getColumnOrNull(name)?.addParentPath(path, host)
20-
public fun getChild(index: Int): ColumnWithPath<Any?>? = asColumnGroup().getColumnOrNull(index)?.addParentPath(path, host)
21-
public fun children(): List<ColumnWithPath<Any?>> = if (isColumnGroup()) data.asColumnGroup().columns().map { it.addParentPath(path, host) } else emptyList()
17+
public fun <C> getChild(accessor: ColumnReference<C>): ColumnWithPath<C>? = asColumnGroup().getColumnOrNull(accessor)?.addPath(path + accessor.path())
18+
public fun getChild(name: String): ColumnWithPath<Any?>? = asColumnGroup().getColumnOrNull(name)?.addParentPath(path)
19+
public fun getChild(index: Int): ColumnWithPath<Any?>? = asColumnGroup().getColumnOrNull(index)?.addParentPath(path)
20+
public fun children(): List<ColumnWithPath<Any?>> = if (isColumnGroup()) data.asColumnGroup().columns().map { it.addParentPath(path) } else emptyList()
2221

2322
override fun path(): ColumnPath = path
2423

src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/DataFrameReceiver.kt

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,24 @@ import org.jetbrains.kotlinx.dataframe.columns.ColumnWithPath
1717
import org.jetbrains.kotlinx.dataframe.columns.SingleColumn
1818
import org.jetbrains.kotlinx.dataframe.columns.UnresolvedColumnsPolicy
1919
import org.jetbrains.kotlinx.dataframe.impl.columns.ColumnGroupWithParent
20+
import org.jetbrains.kotlinx.dataframe.impl.columns.ColumnGroupWithPathImpl
2021
import org.jetbrains.kotlinx.dataframe.impl.columns.addPath
2122
import org.jetbrains.kotlinx.dataframe.impl.columns.missing.MissingColumnGroup
2223
import org.jetbrains.kotlinx.dataframe.impl.columns.missing.MissingDataColumn
2324
import org.jetbrains.kotlinx.dataframe.nrow
2425

26+
private fun <T> DataFrame<T>.unbox(): DataFrame<T> = when (this) {
27+
is ColumnGroupWithParent -> source.unbox()
28+
is ColumnGroupWithPathImpl -> column.unbox()
29+
else -> this
30+
}
31+
32+
internal abstract class DataFrameReceiverBase<T>(protected val df: DataFrame<T>) : DataFrameImpl<T>(df.columns(), df.nrow)
33+
2534
internal open class DataFrameReceiver<T>(
26-
val source: DataFrame<T>,
35+
source: DataFrame<T>,
2736
private val unresolvedColumnsPolicy: UnresolvedColumnsPolicy
28-
) : DataFrameImpl<T>(source.columns(), source.nrow), SingleColumn<DataRow<T>> {
37+
) : DataFrameReceiverBase<T>(source.unbox()), SingleColumn<DataRow<T>> {
2938

3039
private fun <R> DataColumn<R>?.check(path: ColumnPath): DataColumn<R>? =
3140
when (this) {
@@ -38,8 +47,8 @@ internal open class DataFrameReceiver<T>(
3847
else -> this
3948
}
4049

41-
override fun getColumnOrNull(name: String) = source.getColumnOrNull(name).check(pathOf(name))
42-
override fun getColumnOrNull(index: Int) = source.getColumnOrNull(index).check(pathOf(""))
50+
override fun getColumnOrNull(name: String) = df.getColumnOrNull(name).check(pathOf(name))
51+
override fun getColumnOrNull(index: Int) = df.getColumnOrNull(index).check(pathOf(""))
4352

4453
override fun <R> getColumnOrNull(column: ColumnReference<R>): DataColumn<R>? {
4554
val context = ColumnResolutionContext(this, unresolvedColumnsPolicy)
@@ -49,11 +58,11 @@ internal open class DataFrameReceiver<T>(
4958
override fun getColumnOrNull(path: ColumnPath) = super.getColumnOrNull(path).check(path)
5059
override fun <R> getColumnOrNull(column: ColumnSelector<T, R>) = getColumnsImpl(unresolvedColumnsPolicy, column).singleOrNull()
5160

52-
override fun resolveSingle(context: ColumnResolutionContext): ColumnWithPath<DataRow<T>>? = DataColumn.createColumnGroup("", source).addPath(emptyPath(), source)
61+
override fun resolveSingle(context: ColumnResolutionContext): ColumnWithPath<DataRow<T>>? = DataColumn.createColumnGroup("", df).addPath(emptyPath())
5362

54-
override fun columns() = source.columns().map { if (it.isColumnGroup()) ColumnGroupWithParent(null, it.asColumnGroup()) else it }
63+
override fun columns() = df.columns().map { if (it.isColumnGroup()) ColumnGroupWithParent(null, it.asColumnGroup()) else it }
5564

56-
override fun columnNames() = source.columnNames()
65+
override fun columnNames() = df.columnNames()
5766

58-
override fun columnTypes() = source.columnTypes()
67+
override fun columnTypes() = df.columnTypes()
5968
}

src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/move.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ internal fun <T, C> MoveClause<T, C>.afterOrBefore(column: ColumnSelector<T, *>,
3636
val parentPath = targetPath.dropLast(1)
3737
val toInsert = removeResult.removedColumns.map {
3838
val path = parentPath + it.name
39-
ColumnToInsert(path, it.toColumnWithPath<C>(df).data, refNode)
39+
ColumnToInsert(path, it.toColumnWithPath<C>().data, refNode)
4040
}
4141
return removeResult.df.insertImpl(toInsert)
4242
}
@@ -48,7 +48,7 @@ internal fun <T, C> MoveClause<T, C>.moveImpl(
4848
val receiver = object : DataFrameReceiver<T>(df, UnresolvedColumnsPolicy.Fail), ColumnsSelectionDsl<T> {}
4949
val removeResult = df.removeImpl(columns = columns)
5050
val columnsToInsert = removeResult.removedColumns.map {
51-
val col = it.toColumnWithPath<C>(df)
51+
val col = it.toColumnWithPath<C>()
5252
var path = newPathExpression(receiver, col).path()
5353
if (under) path += col.name()
5454
ColumnToInsert(path, col.data, it)

src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/sort.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ internal fun <C> ColumnWithPath<C>.addFlag(flag: SortFlag): ColumnWithPath<C> {
9393
}
9494
}
9595
else -> throw IllegalArgumentException("Can not apply sort flag to column kind ${col.kind}")
96-
}.addPath(path, host)
96+
}.addPath(path)
9797
}
9898

9999
internal class ColumnsWithSortFlag<C>(val column: ColumnSet<C>, val flag: SortFlag) : ColumnSet<C> {

src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/split.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ internal fun <T, C, R> splitImpl(
2929

3030
val toInsert = removeResult.removedColumns.flatMap { node ->
3131

32-
val column = node.toColumnWithPath<C>(clause.df)
32+
val column = node.toColumnWithPath<C>()
3333
val columnCollectors = mutableListOf<ColumnDataCollector>()
3434
for (row in 0 until nrow) {
3535
val value = clause.transform(clause.df[row], column.data[row])

src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/columns/ColumnAccessorImpl.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ internal class ColumnAccessorImpl<T>(val path: ColumnPath) : ColumnAccessor<T> {
2929
df = col.asColumnGroup()
3030
}
3131
}
32-
return col?.cast<T>()?.addPath(path, context.df)
32+
return col?.cast<T>()?.addPath(path)
3333
}
3434

3535
override fun rename(newName: String) = ColumnAccessorImpl<T>(path.dropLast(1) + newName)

0 commit comments

Comments
 (0)