-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add sorting strategy * Update mocks * Add merge sort * Add strategy tests * Bump version * Update dartdoc * Use relative imports * Use mergeSort from package:collection * Mention new sorting strategies in changelog * Split tests * Add missing dot in dartdoc Co-authored-by: Albert Wolszon <[email protected]> Co-authored-by: Albert Wolszon <[email protected]>
- Loading branch information
Showing
10 changed files
with
135 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,36 @@ | ||
import 'rule.dart'; | ||
import 'sorting_strategies/default.dart'; | ||
import 'sorting_strategies/merge.dart'; | ||
import 'sorting_strategy.dart'; | ||
|
||
extension Sorted<T> on Iterable<T> { | ||
/// Returns a sorted list according to the `rules`. Order matters, so if | ||
/// first rule considers two items equal, next one will decide and so on. | ||
List<T> sorted(List<SortedRule> rules) { | ||
if (rules.isEmpty) return List.of(this); | ||
/// | ||
/// A sorting strategy can be provided through `sortingStrategy` which | ||
/// will perform the final sorting procedure. Defaults to [DefaultSortingStrategy]. | ||
/// Consider using [MergeSortingStrategy] if a stable sort is needed. | ||
List<T> sorted( | ||
List<SortedRule> rules, { | ||
SortingStrategy<T>? sortingStrategy, | ||
}) { | ||
sortingStrategy ??= DefaultSortingStrategy<T>(); | ||
|
||
return List.of(this) | ||
..sort((a, b) { | ||
int result = 0; | ||
for (final rule in rules) { | ||
result = rule.compareComplex(a, b); | ||
final list = List.of(this); | ||
|
||
if (result != 0) return result; | ||
} | ||
if (rules.isEmpty) return list; | ||
|
||
return result; | ||
}); | ||
sortingStrategy.sort(list, (a, b) { | ||
int result = 0; | ||
for (final rule in rules) { | ||
result = rule.compareComplex(a, b); | ||
|
||
if (result != 0) return result; | ||
} | ||
|
||
return result; | ||
}); | ||
|
||
return list; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import '../sorting_strategy.dart'; | ||
|
||
/// A [SortingStrategy] which uses Dart's default (unstable) sorting method. | ||
class DefaultSortingStrategy<T> implements SortingStrategy<T> { | ||
const DefaultSortingStrategy(); | ||
|
||
@override | ||
void sort(List<T> list, Comparator<T> comparator) { | ||
list.sort(comparator); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import 'package:collection/collection.dart'; | ||
|
||
import '../sorting_strategy.dart'; | ||
|
||
/// A [SortingStrategy] which uses merge sort, a stable sorting algorithm. | ||
class MergeSortingStrategy<T> implements SortingStrategy<T> { | ||
const MergeSortingStrategy(); | ||
|
||
@override | ||
void sort(List<T> list, Comparator<T> comparator) { | ||
mergeSort(list, compare: comparator); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import 'sorting_strategies/default.dart'; | ||
import 'sorting_strategies/merge.dart'; | ||
|
||
/// Strategy performing the final sorting procedure given a list and a single comparator. | ||
/// | ||
/// See also: | ||
/// | ||
/// * [DefaultSortingStrategy], which uses Dart's default (unstable) sorting method. | ||
/// * [MergeSortingStrategy], which uses merge sort, a stable sorting algorithm. | ||
abstract class SortingStrategy<T> { | ||
/// Sorts [list] in place given a [comparator]. | ||
void sort(List<T> list, Comparator<T> comparator); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import 'package:sorted/sorted.dart'; | ||
import 'package:test/test.dart'; | ||
|
||
void main() { | ||
group('DefaultSortingStrategy', () { | ||
test('sorts the list in-place', () { | ||
final list = [1, 3, 2, 1]; | ||
|
||
const DefaultSortingStrategy<int>().sort(list, (a, b) => a - b); | ||
|
||
expect(list, [1, 1, 2, 3]); | ||
}); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import 'package:sorted/sorted.dart'; | ||
import 'package:test/test.dart'; | ||
|
||
void main() { | ||
group('MergeSortingStrategy', () { | ||
test('sorts the list in-place', () { | ||
final list = [1, 3, 2, 1]; | ||
|
||
const MergeSortingStrategy<int>().sort(list, (a, b) => a - b); | ||
|
||
expect(list, [1, 1, 2, 3]); | ||
}); | ||
|
||
test('sort is stable', () { | ||
final list = [ | ||
{'prop1': 1, 'prop2': 0}, | ||
{'prop1': 3, 'prop2': 0}, | ||
{'prop1': 1, 'prop2': 1}, | ||
{'prop1': 1, 'prop2': 2}, | ||
{'prop1': 2, 'prop2': 0}, | ||
{'prop1': 1, 'prop2': 1}, | ||
]; | ||
|
||
const MergeSortingStrategy<Map<String, int>>() | ||
.sort(list, (a, b) => a['prop1']! - b['prop1']!); | ||
|
||
expect(list, [ | ||
{'prop1': 1, 'prop2': 0}, | ||
{'prop1': 1, 'prop2': 1}, | ||
{'prop1': 1, 'prop2': 2}, | ||
{'prop1': 1, 'prop2': 1}, | ||
{'prop1': 2, 'prop2': 0}, | ||
{'prop1': 3, 'prop2': 0}, | ||
]); | ||
}); | ||
}); | ||
} |