Browse Source

feat(sort_box,neon): ability to presort the values

Signed-off-by: Nikolas Rimikis <rimikis.nikolas@gmail.com>
pull/591/head
Nikolas Rimikis 1 year ago
parent
commit
05c824bf3e
No known key found for this signature in database
GPG Key ID: 85ED1DE9786A4FF2
  1. 6
      packages/neon/neon/lib/src/sort_box/sort_box_builder.dart
  2. 45
      packages/sort_box/lib/sort_box.dart

6
packages/neon/neon/lib/src/sort_box/sort_box_builder.dart

@ -17,6 +17,7 @@ class SortBoxBuilder<T extends Enum, R> extends StatelessWidget {
required this.sortBoxOrderOption, required this.sortBoxOrderOption,
required final List<R>? input, required final List<R>? input,
required this.builder, required this.builder,
this.presort,
super.key, super.key,
}) : input = input ?? []; }) : input = input ?? [];
@ -30,6 +31,9 @@ class SortBoxBuilder<T extends Enum, R> extends StatelessWidget {
/// Child builder using the sorted list. /// Child builder using the sorted list.
final SortBoxWidgetBuilder<R> builder; final SortBoxWidgetBuilder<R> builder;
/// Pre sorts input.
final Set<(T property, SortBoxOrder order)>? presort;
@override @override
Widget build(final BuildContext context) { Widget build(final BuildContext context) {
if (input.length <= 1) { if (input.length <= 1) {
@ -44,7 +48,7 @@ class SortBoxBuilder<T extends Enum, R> extends StatelessWidget {
builder: (final context, final order, final _) { builder: (final context, final order, final _) {
final box = (property, order); final box = (property, order);
return builder(context, sortBox.sort(input, box)); return builder(context, sortBox.sort(input, box, presort));
}, },
), ),
); );

45
packages/sort_box/lib/sort_box.dart

@ -1,22 +1,47 @@
// ignore_for_file: public_member_api_docs /// Signature of a function returning a [Comparable].
typedef ComparableGetter<T> = Comparable Function(T); typedef ComparableGetter<T> = Comparable Function(T);
/// Sorting Box to sort [List]s on multiple properties.
class SortBox<T extends Enum, R> { class SortBox<T extends Enum, R> {
/// Constructs a new SortBox.
///
/// A *Box* is a record of a property and how to order it.
SortBox( SortBox(
this._properties, this._properties,
this._boxes, this._boxes,
); );
/// A mapping of all values [T] to their [ComparableGetter].
final Map<T, ComparableGetter<R>> _properties; final Map<T, ComparableGetter<R>> _properties;
/// A mapping of values [T] to their *Boxes*.
///
/// The Boxes are applied if two elements are considered equal regarding their property [T].
final Map<T, Set<(T property, SortBoxOrder order)>> _boxes; final Map<T, Set<(T property, SortBoxOrder order)>> _boxes;
List<R> sort(final List<R> input, final (T property, SortBoxOrder order) box) { /// Sorts the [input] list according to their [box].
///
/// A box contains the property and [SortBoxOrder] how the list should be sorted.
/// In case the property of two elements is considered equal all following boxes specified at `_boxes[property]` are applied.
/// If specified [presort] will be applied before [box] and [_boxes].
///
/// This function sorts the input in place and a reference to it mutating the provided list.
List<R> sort(
final List<R> input,
final (T property, SortBoxOrder order) box, [
final Set<(T property, SortBoxOrder order)>? presort,
]) {
if (input.length <= 1) { if (input.length <= 1) {
return input; return input;
} }
final sorted = input..sort((final item1, final item2) => _compare(item1, item2, box, _boxes[box.$1]?.iterator)); final boxes = {
...?presort,
box,
...?_boxes[box.$1],
};
final sorted = input..sort((final item1, final item2) => _compare(item1, item2, boxes.iterator..moveNext()));
return sorted; return sorted;
} }
@ -24,9 +49,9 @@ class SortBox<T extends Enum, R> {
int _compare( int _compare(
final R item1, final R item1,
final R item2, final R item2,
final (T property, SortBoxOrder order) box, final Iterator<(T property, SortBoxOrder order)> iterator,
final Iterator<(T property, SortBoxOrder order)>? iterator,
) { ) {
final box = iterator.current;
final (property, sortBoxOrder) = box; final (property, sortBoxOrder) = box;
final comparableGetter = _properties[property]!; final comparableGetter = _properties[property]!;
@ -38,15 +63,19 @@ class SortBox<T extends Enum, R> {
SortBoxOrder.descending => comparable2.compareTo(comparable1), SortBoxOrder.descending => comparable2.compareTo(comparable1),
}; };
if (order == 0 && iterator != null && iterator.moveNext()) { if (order == 0 && iterator.moveNext()) {
return _compare(item1, item2, iterator.current, iterator); return _compare(item1, item2, iterator);
} }
return order; return order;
} }
} }
/// Sorting order used by [SortBox].
enum SortBoxOrder { enum SortBoxOrder {
/// Ascending sorting order.
ascending, ascending,
/// Descending sorting order.
descending, descending,
} }

Loading…
Cancel
Save