Using Flutter/Dart (newbie). I need to store users results in a game (score, time and name). I presume a GameResult class is the way to go?
I then need to order on each users results on date/time (newest to oldest) to display a results table. How can I order on datetime values?
The Dart DateTime class is Comparable to other DateTime
objects, so you can use dateTime1.compareTo(dateTime2)
to compare two points in time.
Example:
class Result implements Comparable<Result> {
final String name;
final int score;
final DateTime time;
Result(this.name, this.score, this.time);
int compareTo(Result other) {
int order = other.score.compareTo(score);
if (order == 0) order = time.compareTo(other.time);
return order;
}
String toString() => "Result($name, score: $score, time: $time)";
}
This creates a class where instances can be compared to each other.
The order is first by reverse score
(higher score before lower score) and for equal scores, it sorts the earlier results before later results.
The Comparable.compareTo
method is specified to return a negative number if the receiver is "before" the argument in the order, zero if they have the same order, and a positive number if the receiver is after the argument.
Integers are comparable too, and by using other.score.compareTo(score)
instead of the other way around, we effectively switch the ordering of the scores - integers default to lower values before higher values).
When the Result
class is comparable to itself, you can sort a List<Result>
as just:
var results = <Result>[
Result("Me", 0, DateTime.now().subtract(Duration(hours: 1))),
Result("Me again", 0, DateTime.now().subtract(Duration(hours: 2))),
Result("You", 1000000, DateTime.now().subtract(Duration(hours: 24))),
];
results.sort();
print(results.join("\n"));
This prints:
Result(You, score: 1000000, time: 2018-10-23 15:34:16.532)
Result(Me again, score: 0, time: 2018-10-24 13:34:16.532)
Result(Me, score: 0, time: 2018-10-24 14:34:16.531)
You win by score. My earlier zero-score is before my later one.
One approach is to evaluate the dates as Epoch DateTime millisecondsSinceEpoch
then sort as standard int values.
With this approach you can sort an entire list in one line...
result.sort((a,b) => a.date.millisecondsSinceEpoch.compareTo(b.date.millisecondsSinceEpoch));
Here is a complete example using the Game Result scenario
// Create the game result object
class Result{
Result(this.name, this.score, this.date);
String name;
int score;
DateTime date;
@override
String toString() => '$name $score $date';
}
// Create a list to put the results in
List<Result> result = [];
// Populate the list with results
result..add( Result('Tom', 850, DateTime.tryParse('2020-01-10')))
..add( Result('Dic', 600, DateTime.tryParse('2020-01-03')))
..add( Result('Harry', 450, DateTime.tryParse('2020-01-05')));
// print the unsorted list
print(result);
// Sort the list by datetime property
result.sort((a,b) => a.date.millisecondsSinceEpoch.compareTo(b.date.millisecondsSinceEpoch));
// print the sorted list
print(result);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With