withRowsOrderedBy method
A new data frame with the rows ordered by the values in columns
.
Example:
final d = """
x,y,z
9,3,bat
3,6,zebra
7,4,moose
3,8,bat
8,4,zebra
6,5,bat,
1,7,zebra
3,9,moose
""".parseAsCsv();
print(d.withRowsOrderedBy(["z", "x"]));
.-.-.-------.
|x|y|z |
:-+-+-------:
|3|8|bat |
|6|5|bat |
|9|3|bat |
|3|9|moose |
|7|4|moose |
|1|7|zebra |
|3|6|zebra |
|8|4|zebra |
'-'-'-------'
Implementation
DataFrame withRowsOrderedBy(
List<String> columns, {
bool decreasing = false,
}) {
int compareLists(
List<int> a,
List<int> b, [
int index = 0,
]) =>
index == a.length
? 0
: (a[index] > b[index]
? 1
: (a[index] < b[index]
? -1
: compareLists(
a,
b,
index + 1,
)));
final orderCriterion = [
for (var _ = 0; _ < rowNumber; _++)
[for (var _ = 0; _ < columns.length; _++) 0]
],
uniqueNumeric = {
for (final MapEntry(:key, :value) in numericColumns.entries)
key: NumericColumn(value.uniqueValues)
},
uniqueNumericIndexOrders = <String, Map<num, int>>{},
uniqueCategoric = {
for (final MapEntry(:key, :value) in categoricColumns.entries)
key: CategoricColumn(value.uniqueValues)
},
uniqueCategoricIndexOrders = <String, Map<String, int>>{};
for (final MapEntry(:key, :value) in uniqueNumeric.entries) {
final indexOrders = value.indexOrders;
uniqueNumericIndexOrders[key] = {};
for (var i = 0; i < value.length; i++) {
uniqueNumericIndexOrders[key]![value[i]] = indexOrders[i];
}
}
for (final MapEntry(:key, :value) in uniqueCategoric.entries) {
final indexOrders = value.indexOrders;
uniqueCategoricIndexOrders[key] = {};
for (var i = 0; i < value.length; i++) {
uniqueCategoricIndexOrders[key]![value[i]] = indexOrders[i];
}
}
void updateIndexOrders(List<int> indexOrders, int index) {
for (var i = 0; i < rowNumber; i++) {
orderCriterion[i][index] = indexOrders[i];
}
}
for (var i = 0; i < columns.length; i++) {
final columnName = columns[i];
if (numericColumns.containsKey(columnName)) {
updateIndexOrders([
for (final x in numericColumns[columnName]!.values)
uniqueNumericIndexOrders[columnName]![x]!
], i);
} else if (categoricColumns.containsKey(columnName)) {
updateIndexOrders([
for (final x in categoricColumns[columnName]!.values)
uniqueCategoricIndexOrders[columnName]![x]!
], i);
} else {
throw PackhorseError.badColumnName(columnName);
}
}
final orderedIndices = [for (var i = 0; i < rowNumber; i++) i]
..sort((a, b) => compareLists(orderCriterion[a], orderCriterion[b]));
return withRowsAtIndices(orderedIndices);
}