Skip to content

Commit 179595e

Browse files
authored
Merge pull request #1517 from CarloMariaProietti/insert_before
Add insert.before { }
2 parents 3df22f0 + 8a30f96 commit 179595e

File tree

4 files changed

+89
-4
lines changed

4 files changed

+89
-4
lines changed

core/api/core.api

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2609,6 +2609,8 @@ public final class org/jetbrains/kotlinx/dataframe/api/InsertKt {
26092609
public static final fun after (Lorg/jetbrains/kotlinx/dataframe/api/InsertClause;Lorg/jetbrains/kotlinx/dataframe/columns/ColumnAccessor;)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
26102610
public static final fun after (Lorg/jetbrains/kotlinx/dataframe/api/InsertClause;Lorg/jetbrains/kotlinx/dataframe/columns/ColumnPath;)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
26112611
public static final fun at (Lorg/jetbrains/kotlinx/dataframe/api/InsertClause;I)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
2612+
public static final fun before (Lorg/jetbrains/kotlinx/dataframe/api/InsertClause;Ljava/lang/String;)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
2613+
public static final fun before (Lorg/jetbrains/kotlinx/dataframe/api/InsertClause;Lkotlin/jvm/functions/Function2;)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
26122614
public static final fun insert (Lorg/jetbrains/kotlinx/dataframe/DataFrame;Lorg/jetbrains/kotlinx/dataframe/DataColumn;)Lorg/jetbrains/kotlinx/dataframe/api/InsertClause;
26132615
public static final fun under (Lorg/jetbrains/kotlinx/dataframe/api/InsertClause;Ljava/lang/String;)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
26142616
public static final fun under (Lorg/jetbrains/kotlinx/dataframe/api/InsertClause;Lkotlin/jvm/functions/Function2;)Lorg/jetbrains/kotlinx/dataframe/DataFrame;

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

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import org.jetbrains.kotlinx.dataframe.documentation.ExcludeFromSources
1616
import org.jetbrains.kotlinx.dataframe.documentation.Indent
1717
import org.jetbrains.kotlinx.dataframe.documentation.LineBreak
1818
import org.jetbrains.kotlinx.dataframe.documentation.SelectingColumns
19+
import org.jetbrains.kotlinx.dataframe.impl.api.afterImpl
20+
import org.jetbrains.kotlinx.dataframe.impl.api.beforeImpl
1921
import org.jetbrains.kotlinx.dataframe.impl.api.insertImpl
2022
import org.jetbrains.kotlinx.dataframe.impl.columnName
2123
import org.jetbrains.kotlinx.dataframe.impl.removeAt
@@ -338,10 +340,59 @@ public fun <T> InsertClause<T>.after(columnPath: ColumnPath): DataFrame<T> {
338340
return df.insertImpl(dstPath, column).move { dstPath }.after { columnPath }
339341
}
340342

341-
internal fun <T> InsertClause<T>.afterImpl(columnPath: ColumnPath): DataFrame<T> {
342-
val dstPath = ColumnPath(columnPath.removeAt(columnPath.size - 1) + column.name())
343-
return df.insertImpl(dstPath, column).move { dstPath }.after { columnPath }
344-
}
343+
// endregion
344+
345+
// region before
346+
347+
/**
348+
* Inserts the new column previously specified with [insert]
349+
* at the position immediately before the selected [column] (on the same level).
350+
*
351+
* For more information: {@include [DocumentationUrls.Insert]}
352+
*
353+
* See [Grammar][InsertDocs.Grammar] for more details.
354+
*
355+
* See also: [SelectingColumns.Dsl].
356+
*
357+
* ### Examples:
358+
* ```kotlin
359+
* // Insert a new column "age" before the "name" column
360+
* df.insert(age).before { name }
361+
*
362+
* // Insert a new column "sum" before the nested "min" column (inside the "stats" column group)
363+
* val dfWithSum = df.insert("sum") { a + b }.before { stats.min }
364+
* ```
365+
*
366+
* @param [column] The [ColumnSelector] used to choose an existing column in this [DataFrame],
367+
* before which the new column will be inserted.
368+
* @return A new [DataFrame] with the inserted column placed before the selected column.
369+
*/
370+
@Refine
371+
@Interpretable("InsertBefore0")
372+
public fun <T> InsertClause<T>.before(column: ColumnSelector<T, *>): DataFrame<T> = beforeImpl(df.getColumnPath(column))
373+
374+
/**
375+
* Inserts the new column previously specified with [insert]
376+
* at the position immediately before the column with the given [name][column].
377+
*
378+
* For more information: {@include [DocumentationUrls.Insert]}
379+
*
380+
* See [Grammar][InsertDocs.Grammar] for more details.
381+
*
382+
* See also: [SelectingColumns.ColumnNames].
383+
*
384+
* ### Example
385+
* ```kotlin
386+
* // Insert a new column "age" before the "name" column
387+
* df.insert(age).before("name")
388+
* ```
389+
*
390+
* @param [column] The [String] name of the column in this [DataFrame]
391+
* before which the new column will be inserted.
392+
* @return A new [DataFrame] with the inserted column placed before the specified column.
393+
*/
394+
public fun <T> InsertClause<T>.before(column: String): DataFrame<T> =
395+
df.add(this.column).move(this.column).before(column)
345396

346397
// endregion
347398

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,19 @@ import org.jetbrains.kotlinx.dataframe.AnyBaseCol
44
import org.jetbrains.kotlinx.dataframe.AnyCol
55
import org.jetbrains.kotlinx.dataframe.DataColumn
66
import org.jetbrains.kotlinx.dataframe.DataFrame
7+
import org.jetbrains.kotlinx.dataframe.api.InsertClause
8+
import org.jetbrains.kotlinx.dataframe.api.after
9+
import org.jetbrains.kotlinx.dataframe.api.before
710
import org.jetbrains.kotlinx.dataframe.api.cast
11+
import org.jetbrains.kotlinx.dataframe.api.move
812
import org.jetbrains.kotlinx.dataframe.api.toDataFrame
913
import org.jetbrains.kotlinx.dataframe.columns.ColumnGroup
1014
import org.jetbrains.kotlinx.dataframe.columns.ColumnPath
1115
import org.jetbrains.kotlinx.dataframe.impl.columns.tree.ReadonlyTreeNode
1216
import org.jetbrains.kotlinx.dataframe.impl.columns.tree.ReferenceData
1317
import org.jetbrains.kotlinx.dataframe.impl.columns.tree.getAncestor
1418
import org.jetbrains.kotlinx.dataframe.impl.columns.withDf
19+
import org.jetbrains.kotlinx.dataframe.impl.removeAt
1520

1621
internal data class ColumnToInsert(
1722
val insertionPath: ColumnPath,
@@ -148,3 +153,13 @@ internal fun <T> insertImpl(
148153

149154
return newColumns.toDataFrame().cast()
150155
}
156+
157+
internal fun <T> InsertClause<T>.afterImpl(columnPath: ColumnPath): DataFrame<T> {
158+
val dstPath = ColumnPath(columnPath.removeAt(columnPath.size - 1) + column.name())
159+
return df.insertImpl(dstPath, column).move { dstPath }.after { columnPath }
160+
}
161+
162+
internal fun <T> InsertClause<T>.beforeImpl(columnPath: ColumnPath): DataFrame<T> {
163+
val dstPath = ColumnPath(columnPath.removeAt(columnPath.size - 1) + column.name())
164+
return df.insertImpl(dstPath, column).move { dstPath }.before { columnPath }
165+
}

core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/DataFrameTreeTests.kt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import org.jetbrains.kotlinx.dataframe.api.asDataFrame
2525
import org.jetbrains.kotlinx.dataframe.api.asFrame
2626
import org.jetbrains.kotlinx.dataframe.api.asGroupBy
2727
import org.jetbrains.kotlinx.dataframe.api.at
28+
import org.jetbrains.kotlinx.dataframe.api.before
2829
import org.jetbrains.kotlinx.dataframe.api.by
2930
import org.jetbrains.kotlinx.dataframe.api.cast
3031
import org.jetbrains.kotlinx.dataframe.api.colsOf
@@ -702,6 +703,22 @@ class DataFrameTreeTests : BaseTest() {
702703
typed2.insert(colName) { nameAndCity.name.reversed() }.after { nameAndCity.name }.check()
703704
}
704705

706+
@Test
707+
fun `insert column before`() {
708+
val colName = "reversed"
709+
710+
fun DataFrame<GroupedPerson>.check() {
711+
nameAndCity.columnsCount() shouldBe 3
712+
nameAndCity.columnNames() shouldBe listOf(
713+
typed2.nameAndCity.name.name(),
714+
colName,
715+
typed2.nameAndCity.city.name(),
716+
)
717+
}
718+
719+
typed2.insert(colName) { nameAndCity.name.reversed() }.before { nameAndCity.city }.check()
720+
}
721+
705722
@Test
706723
fun append() {
707724
val res = typed2.append(listOf("Bill", "San Francisco"), null, 66)

0 commit comments

Comments
 (0)