@@ -8,23 +8,29 @@ import org.jetbrains.kotlinx.dataframe.api.ColumnsSelectionDsl
88import org.jetbrains.kotlinx.dataframe.api.MoveClause
99import org.jetbrains.kotlinx.dataframe.api.after
1010import org.jetbrains.kotlinx.dataframe.api.asColumnGroup
11+ import org.jetbrains.kotlinx.dataframe.api.asDataFrame
1112import org.jetbrains.kotlinx.dataframe.api.before
1213import org.jetbrains.kotlinx.dataframe.api.cast
1314import org.jetbrains.kotlinx.dataframe.api.getColumn
1415import org.jetbrains.kotlinx.dataframe.api.getColumnGroup
1516import org.jetbrains.kotlinx.dataframe.api.getColumnWithPath
1617import org.jetbrains.kotlinx.dataframe.api.getColumns
1718import org.jetbrains.kotlinx.dataframe.api.move
19+ import org.jetbrains.kotlinx.dataframe.api.to
1820import org.jetbrains.kotlinx.dataframe.api.toDataFrame
21+ import org.jetbrains.kotlinx.dataframe.api.toPath
1922import org.jetbrains.kotlinx.dataframe.columns.ColumnPath
2023import org.jetbrains.kotlinx.dataframe.columns.ColumnWithPath
2124import org.jetbrains.kotlinx.dataframe.columns.UnresolvedColumnsPolicy
2225import org.jetbrains.kotlinx.dataframe.columns.toColumnSet
2326import org.jetbrains.kotlinx.dataframe.impl.DataFrameReceiver
27+ import org.jetbrains.kotlinx.dataframe.impl.aggregation.toColumns
2428import org.jetbrains.kotlinx.dataframe.impl.asList
29+ import org.jetbrains.kotlinx.dataframe.impl.columns.toColumnSet
2530import org.jetbrains.kotlinx.dataframe.impl.columns.toColumnWithPath
2631import org.jetbrains.kotlinx.dataframe.impl.columns.tree.ColumnPosition
2732import org.jetbrains.kotlinx.dataframe.impl.columns.tree.getOrPut
33+ import org.jetbrains.kotlinx.dataframe.impl.last
2834import org.jetbrains.kotlinx.dataframe.path
2935
3036internal fun <T , C > MoveClause <T , C >.afterOrBefore (column : ColumnSelector <T , * >, isAfter : Boolean ): DataFrame <T > {
@@ -148,54 +154,15 @@ internal fun <T, C> MoveClause<T, C>.moveToImpl(columnIndex: Int, insideGroup: B
148154 return moveTo(columnIndex)
149155 }
150156
151- // columns are nested and will be eventually moved inside their own group
152- // finding reference column
157+ // idea: remove columns to move and brothers (sons), apply moveTo to sons, insert sons
153158 val parentPath = df[parentOfFirst].path
154- val referenceAndSiblings = df[parentOfFirst].asColumnGroup().columns()
155- val referenceAndSiblingsPaths = referenceAndSiblings.map { parentPath + it.path }
156- val reference = if (columnIndex >= referenceAndSiblingsPaths.size) {
157- referenceAndSiblingsPaths.last()
158- } else {
159- referenceAndSiblingsPaths[columnIndex]
160- }
161-
162- // two cases : columns to move are before, or after, the reference
163- val columnsBeforeReferenceToMove = mutableListOf<ColumnPath >()
164- val columnsAfterReferenceToMove = mutableListOf<ColumnPath >()
165- val columnsToMovePath = columnsToMove.map { it.path }
166- var referenceWasIterated = false
167- referenceAndSiblingsPaths.forEach {
168- if (it.path.last() == reference.path.last()) {
169- referenceWasIterated = true
170- } else {
171- if (columnsToMovePath.contains(it)) {
172- if (referenceWasIterated) {
173- columnsAfterReferenceToMove.add(it)
174- } else {
175- columnsBeforeReferenceToMove.add(it)
176- }
177- }
178- }
179- }
180-
181- // move columns
182- when {
183- columnsBeforeReferenceToMove.isNotEmpty() && columnsAfterReferenceToMove.isNotEmpty() -> {
184- val intermediateDf = df.move { columnsBeforeReferenceToMove.toColumnSet() }.after { reference }
185- val newReference = columnsBeforeReferenceToMove.last()
186- val finalDf = intermediateDf.move { columnsAfterReferenceToMove.toColumnSet() }.after { newReference }
187- return finalDf
188- }
189-
190- columnsBeforeReferenceToMove.isNotEmpty() -> {
191- return df.move { columnsBeforeReferenceToMove.toColumnSet() }.after { reference }
192- }
193-
194- columnsAfterReferenceToMove.isNotEmpty() -> {
195- return df.move { columnsAfterReferenceToMove.toColumnSet() }.before { reference }
196- }
197-
198- // if it is not needed to move any of the nested columns
199- else -> return df
200- }
159+ val sons = df[parentOfFirst].asColumnGroup()
160+ // remove columns to move and their siblings
161+ val sonsPaths = sons.columns().map { parentPath + it.path }
162+ val intermediateDf = df.removeImpl { sonsPaths.toColumnSet() }
163+ // move columns and insert back
164+ val columnsToMoveWithReducedPath = columnsToMove.map { it.path.last(it.path.size - parentPath.size).toPath() }
165+ val columnsMoved = sons.asDataFrame().move { columnsToMoveWithReducedPath.toColumnSet() }.to(columnIndex).columns()
166+ val columnsMovedPaths = columnsMoved.map { ColumnToInsert (parentPath + it.path, it ) }
167+ return intermediateDf.df.insertImpl(columnsMovedPaths)
201168}
0 commit comments