@@ -11,12 +11,12 @@ import org.jetbrains.kotlinx.dataframe.Selector
11
11
import org.jetbrains.kotlinx.dataframe.api.AddDataRow
12
12
import org.jetbrains.kotlinx.dataframe.api.Update
13
13
import org.jetbrains.kotlinx.dataframe.api.asColumnGroup
14
+ import org.jetbrains.kotlinx.dataframe.api.asDataFrame
14
15
import org.jetbrains.kotlinx.dataframe.api.cast
15
16
import org.jetbrains.kotlinx.dataframe.api.indices
16
17
import org.jetbrains.kotlinx.dataframe.api.isEmpty
17
18
import org.jetbrains.kotlinx.dataframe.api.name
18
19
import org.jetbrains.kotlinx.dataframe.api.replace
19
- import org.jetbrains.kotlinx.dataframe.api.rows
20
20
import org.jetbrains.kotlinx.dataframe.api.toColumn
21
21
import org.jetbrains.kotlinx.dataframe.api.toDataFrame
22
22
import org.jetbrains.kotlinx.dataframe.api.with
@@ -53,34 +53,37 @@ internal fun <T, C> Update<T, C>.updateWithValuePerColumnImpl(selector: Selector
53
53
internal fun <T , C , R > Update <T , DataRow <C >>.asFrameImpl (expression : DataFrameExpression <C , DataFrame <R >>): DataFrame <T > =
54
54
if (df.isEmpty()) df
55
55
else df.replace(columns).with {
56
- val src = it.asColumnGroup()
57
- val updatedColumn = expression(src, src).asColumnGroup(src.name())
56
+ // First, we create an updated column group with the result of the expression
57
+ val srcColumnGroup = it.asColumnGroup()
58
+ val updatedColumnGroup = srcColumnGroup
59
+ .asDataFrame()
60
+ .let { expression(it, it) }
61
+ .asColumnGroup(srcColumnGroup.name())
62
+
58
63
if (filter == null ) {
59
- // If there is no filter, we simply replace the selected column groups with the result of the expression
60
- updatedColumn
64
+ // If there is no filter, we simply return the updated column group
65
+ updatedColumnGroup
61
66
} else {
62
- // If there is a filter, we collect the indices of the rows that are inside the filter
63
- val collector = createDataCollector<DataRow <C >>(it.size, it.type)
64
- val indices = buildList {
65
- df.indices().forEach { rowIndex ->
66
- val row = AddDataRowImpl (rowIndex, df, collector.values)
67
- val currentValue = row[src]
67
+ // If there is a filter, then we replace the rows of the source column group with the updated column group
68
+ // only if they satisfy the filter
69
+ srcColumnGroup.replaceRowsIf(from = updatedColumnGroup) {
70
+ val srcRow = df[it.index]
71
+ val srcValue = srcRow[srcColumnGroup]
68
72
69
- if (filter.invoke(row, currentValue)) {
70
- this + = rowIndex
71
- collector.add(currentValue)
72
- }
73
- }
73
+ filter.invoke(srcRow, srcValue)
74
74
}
75
-
76
- // Then we only replace the original rows with the updated rows that are inside the filter
77
- src.rows().map {
78
- val index = indices.indexOf(it.index)
79
- if (index == - 1 ) it else updatedColumn[index]
80
- }.toColumn(src.name)
81
75
}
82
76
}
83
77
78
+ private fun <C , R > ColumnGroup<C>.replaceRowsIf (
79
+ from : ColumnGroup <R >,
80
+ condition : (DataRow <C >) -> Boolean = { true },
81
+ ): ColumnGroup <C > = values()
82
+ .map { if (condition(it)) from[it.index] else it }
83
+ .toColumn(name)
84
+ .asColumnGroup()
85
+ .cast()
86
+
84
87
internal fun <T , C > DataColumn<C>.updateImpl (
85
88
df : DataFrame <T >,
86
89
filter : RowValueFilter <T , C >? ,
0 commit comments