@@ -83,18 +83,33 @@ fun List<Row>.print(separator: String = "\t") = asSequence().print(separator)
83
83
/* * Internal representations for column selection indices. Usually not use directly but rather via [with] and [without].
84
84
*/
85
85
abstract class ColSelect (val indices : Array <Int > = emptyArray()) {
86
+
87
+ // irrespective of selection mode (positive or negative) indices must be positive in here
88
+ init {
89
+ stopIfNot(indices.all { it > 0 }) {
90
+ " kscript.text.* is using 1-based arrays to ease awk transition, so indices must be strictly positive"
91
+ }
92
+ }
93
+
86
94
abstract fun and (column : Int ): ColSelect
87
95
abstract fun and (range : IntRange ): ColSelect
96
+ abstract fun process (lines : Sequence <Row >): Sequence <Row >
88
97
}
89
98
90
- class PosSelect (arrayOf : Array <Int >) : ColSelect(arrayOf ) {
99
+ class PosSelect (columnIndices : Array <Int >) : ColSelect(columnIndices ) {
91
100
override fun and (column : Int ) = PosSelect (arrayOf(* indices, column))
92
101
override fun and (range : IntRange ) = PosSelect (arrayOf(* indices, * range.toList().toTypedArray()))
102
+
103
+ override fun process (lines : Sequence <Row >): Sequence <Row > = lines.map { row -> Row (indices.map { row[it] }) }
93
104
}
94
105
95
- class NegSelect (arrayOf : Array <Int >) : ColSelect(arrayOf ) {
106
+ class NegSelect (columnIndices : Array <Int >) : ColSelect(columnIndices ) {
96
107
override fun and (column : Int ) = NegSelect (arrayOf(* indices, column))
97
108
override fun and (range : IntRange ) = NegSelect (arrayOf(* indices, * range.toList().toTypedArray()))
109
+
110
+ override fun process (lines : Sequence <Row >): Sequence <Row > = lines.map {
111
+ Row (it.filterIndexed { index, _ -> ! indices.contains(index+ 1 ) })
112
+ }
98
113
}
99
114
100
115
/* * Starts building a column selection index. Both positive and negative indices are supported. */
@@ -116,24 +131,20 @@ fun Sequence<Row>.select(vararg colIndices: Int): Sequence<Row> {
116
131
" Can not mix positive and negative selections"
117
132
}
118
133
119
- val selector = if (isPositive) PosSelect (arrayOf(* colIndices.toTypedArray())) else NegSelect (arrayOf(* colIndices.toTypedArray()))
134
+ val selector = if (isPositive) {
135
+ PosSelect (arrayOf(* colIndices.toTypedArray()))
136
+ } else {
137
+ NegSelect (arrayOf(* colIndices.map { - it }.toTypedArray()))
138
+ }
120
139
121
140
return select(selector)
122
141
}
123
142
124
- fun Sequence<Row>.select (columns : ColSelect ): Sequence <Row > {
143
+ fun Sequence<Row>.select (columnSelector : ColSelect ): Sequence <Row > {
125
144
// more efficient but does not allow to change the order
126
- // return map { it.filterIndexed { index, _ -> retainColumn(columns, index + 1) } }
127
-
128
- stopIfNot(columns.indices.all { it != 0 }) { " kscript.text.* is using 1-based arrays to ease awk transition" }
145
+ // return map { it.filterIndexed { index, _ -> retainColumn(columnSelector, index + 1) } }
129
146
130
- return if (columns is PosSelect ) {
131
- // positive selection
132
- map { row -> Row (columns.indices.map { row[it] }) }
133
- } else {
134
- // negative selection
135
- map { Row (it.filterIndexed { index, _ -> ! columns.indices.contains(index) }) }
136
- }
147
+ return columnSelector.process(this )
137
148
}
138
149
139
150
0 commit comments