ordered_iterable 1.0.8
ordered_iterable: ^1.0.8 copied to clipboard
Ordered iterable is a library for multi-level (hierarchical) sorting of collections (orderBy, orderByDescending, thenBy, thenByDescending).
Ordered iterable #
Ordered iterable is a library for multi-level (hierarchical) sorting of collections (orderBy, orderByDescending, thenBy, thenByDescending).
Version: 1.0.8
About this software #
Ordered iterable is a library for multi-level (hierarchical) sorting of collections (orderBy, orderByDescending, thenBy, thenByDescending).
It implements methods that allows sorting collections by more than one key simultaneously.
Hierarchical sorting defines a primary sort key, and subsequent keys (secondary, tertiary) sort the elements within previous higher-level groups.
List of sorting methods:
- orderBy (Iterable, primary)
- orderByDescending (Iterable, primary)
- thenBy (OrderedIterable, subsequent)
- thenByDescending (OrderedIterable, subsequent)
Sorting of data containing null is supported.
Sorting of non-comparable data (data that does not implement the Comparable interface) is supported by using custom comparers.
Practical use #
A practical use is sorting collections with additional ordering.
Example:
import 'package:ordered_iterable/ordered_iterable.dart';
void main() {
_sortNumbersInDescendingOrder();
_sortFruitsAndVegetablesByTypeThenByNameDescending();
_sortOrdersByDateThenByStatusThenByAmountDescending();
_sortPersonsByNameThenByAgeDescending();
}
DateTime _date(String date) {
return DateTime.parse(date);
}
void _print<E>(Iterable<E> collection) {
print('-' * 40);
for (final element in collection) {
print(element);
}
}
void _sortFruitsAndVegetablesByTypeThenByNameDescending() {
const source = [
('fruit', 'banana'),
('vegetables', 'spinach'),
('fruit', 'mango'),
('vegetables', 'cucumbers'),
('fruit', 'apple'),
('vegetables', 'potato'),
];
final result = source.orderBy((x) => x.$1).thenByDescending((x) => x.$2);
_print(source);
_print(result);
}
void _sortNumbersInDescendingOrder() {
const source = [
(1, 1, 1),
(2, 3, 3),
(1, 1, 2),
(2, 2, 1),
(1, 2, 3),
(2, 2, 2),
];
final result = source
.orderByDescending((x) => x.$1)
.thenByDescending((x) => x.$2)
.thenByDescending((x) => x.$3);
_print(source);
_print(result);
}
void _sortOrdersByDateThenByStatusThenByAmountDescending() {
final orders = [
(_date('20250102'), OrderStatus.shipped, 150.00),
(_date('20250101'), OrderStatus.canceled, 100.00),
(_date('20250102'), OrderStatus.shipped, 200.00),
(_date('20250101'), OrderStatus.pending, 200.00),
(_date('20250102'), OrderStatus.pending, 100.00),
(_date('20250101'), OrderStatus.pending, 1000.00),
(_date('20250102'), OrderStatus.pending, 1500.00),
];
final byStatus =
Comparer.create<OrderStatus>((a, b) => a.name.compareTo(b.name));
final result = orders
.orderBy((x) => x.$1)
.thenBy((x) => x.$2, byStatus)
.thenByDescending((x) => x.$3);
_print(orders);
_print(result);
}
void _sortPersonsByNameThenByAgeDescending() {
final source = [
_Person('Jarry', 19),
_Person('Jarry', 22),
_Person('John', 20),
null,
_Person('Jack', 21),
];
final byName = Comparer.create<_Person>((a, b) => a.name.compareTo(b.name));
final byAge = Comparer.create<_Person>((a, b) => a.age.compareTo(b.age));
final result =
source.orderBy((x) => x, byName).thenByDescending((x) => x, byAge);
_print(source);
_print(result);
}
enum OrderStatus { canceled, created, pending, shipped }
class _Person {
final int age;
final String name;
_Person(this.name, this.age);
@override
String toString() {
return '$name ($age)';
}
}
Output:
----------------------------------------
(1, 1, 1)
(2, 3, 3)
(1, 1, 2)
(2, 2, 1)
(1, 2, 3)
(2, 2, 2)
----------------------------------------
(2, 3, 3)
(2, 2, 2)
(2, 2, 1)
(1, 2, 3)
(1, 1, 2)
(1, 1, 1)
----------------------------------------
(fruit, banana)
(vegetables, spinach)
(fruit, mango)
(vegetables, cucumbers)
(fruit, apple)
(vegetables, potato)
----------------------------------------
(fruit, mango)
(fruit, banana)
(fruit, apple)
(vegetables, spinach)
(vegetables, potato)
(vegetables, cucumbers)
----------------------------------------
(2025-01-02 00:00:00.000, OrderStatus.shipped, 150.0)
(2025-01-01 00:00:00.000, OrderStatus.canceled, 100.0)
(2025-01-02 00:00:00.000, OrderStatus.shipped, 200.0)
(2025-01-01 00:00:00.000, OrderStatus.pending, 200.0)
(2025-01-02 00:00:00.000, OrderStatus.pending, 100.0)
(2025-01-01 00:00:00.000, OrderStatus.pending, 1000.0)
(2025-01-02 00:00:00.000, OrderStatus.pending, 1500.0)
----------------------------------------
(2025-01-01 00:00:00.000, OrderStatus.canceled, 100.0)
(2025-01-01 00:00:00.000, OrderStatus.pending, 1000.0)
(2025-01-01 00:00:00.000, OrderStatus.pending, 200.0)
(2025-01-02 00:00:00.000, OrderStatus.pending, 1500.0)
(2025-01-02 00:00:00.000, OrderStatus.pending, 100.0)
(2025-01-02 00:00:00.000, OrderStatus.shipped, 200.0)
(2025-01-02 00:00:00.000, OrderStatus.shipped, 150.0)
----------------------------------------
Jarry (19)
Jarry (22)
John (20)
null
Jack (21)
----------------------------------------
null
Jack (21)
Jarry (22)
Jarry (19)
John (20)