From 05c824bf3e09d7bef10f33fa873acc4112fe4710 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Fri, 25 Aug 2023 13:32:13 +0200 Subject: [PATCH] feat(sort_box,neon): ability to presort the values Signed-off-by: Nikolas Rimikis --- .../lib/src/sort_box/sort_box_builder.dart | 6 ++- packages/sort_box/lib/sort_box.dart | 45 +++++++++++++++---- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/packages/neon/neon/lib/src/sort_box/sort_box_builder.dart b/packages/neon/neon/lib/src/sort_box/sort_box_builder.dart index 29d7f58d..afa7227b 100644 --- a/packages/neon/neon/lib/src/sort_box/sort_box_builder.dart +++ b/packages/neon/neon/lib/src/sort_box/sort_box_builder.dart @@ -17,6 +17,7 @@ class SortBoxBuilder extends StatelessWidget { required this.sortBoxOrderOption, required final List? input, required this.builder, + this.presort, super.key, }) : input = input ?? []; @@ -30,6 +31,9 @@ class SortBoxBuilder extends StatelessWidget { /// Child builder using the sorted list. final SortBoxWidgetBuilder builder; + /// Pre sorts input. + final Set<(T property, SortBoxOrder order)>? presort; + @override Widget build(final BuildContext context) { if (input.length <= 1) { @@ -44,7 +48,7 @@ class SortBoxBuilder extends StatelessWidget { builder: (final context, final order, final _) { final box = (property, order); - return builder(context, sortBox.sort(input, box)); + return builder(context, sortBox.sort(input, box, presort)); }, ), ); diff --git a/packages/sort_box/lib/sort_box.dart b/packages/sort_box/lib/sort_box.dart index 733238ac..c7e4eca4 100644 --- a/packages/sort_box/lib/sort_box.dart +++ b/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 = Comparable Function(T); +/// Sorting Box to sort [List]s on multiple properties. class SortBox { + /// Constructs a new SortBox. + /// + /// A *Box* is a record of a property and how to order it. SortBox( this._properties, this._boxes, ); + /// A mapping of all values [T] to their [ComparableGetter]. final Map> _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> _boxes; - List sort(final List 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 sort( + final List input, + final (T property, SortBoxOrder order) box, [ + final Set<(T property, SortBoxOrder order)>? presort, + ]) { if (input.length <= 1) { 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; } @@ -24,9 +49,9 @@ class SortBox { int _compare( final R item1, 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 comparableGetter = _properties[property]!; @@ -38,15 +63,19 @@ class SortBox { SortBoxOrder.descending => comparable2.compareTo(comparable1), }; - if (order == 0 && iterator != null && iterator.moveNext()) { - return _compare(item1, item2, iterator.current, iterator); + if (order == 0 && iterator.moveNext()) { + return _compare(item1, item2, iterator); } return order; } } +/// Sorting order used by [SortBox]. enum SortBoxOrder { + /// Ascending sorting order. ascending, + + /// Descending sorting order. descending, }