Comment trier une liste d'objets par l'ordre alphabétique d'une de ses propriétés (pas le nom mais la valeur réelle que la propriété contient) ?
Comment le trie-t-on dans l'ordre décroissant
Comment trier une liste d'objets par l'ordre alphabétique d'une de ses propriétés (pas le nom mais la valeur réelle que la propriété contient) ?
Vous pouvez passer une fonction de comparaison à List.sort
.
someObjects.sort((a, b) => a.someProperty.compareTo(b.someProperty));
Pour le renverser, vous pourriez faire b.someProperty.compareTo(a.someProperty)
. Ou le trier puis utiliser .reversed
.
Voici ma contribution à cette bonne question. Si quelqu'un éprouve des difficultés à comprendre comment fonctionne la réponse de @Nate Bosch et que vous souhaitez trier la liste de votre classe modèle personnalisée, vous pouvez le faire de cette manière.
1. Vous devez implémenter la classe abstraite Comparable
dans votre classe modèle. Elle possède la méthode compareTo
que vous devez remplacer. Par exemple, j'ai cette classe modèle StudentMarks
qui a une propriété de notes.
class StudentMarks implements Comparable {
int marks;
StudentMarks({
this.marks,
});
@override
int compareTo(other) {
if (this.marks == null || other == null) {
return null;
}
if (this.marks < other.marks) {
return 1;
}
if (this.marks > other.marks) {
return -1;
}
if (this.marks == other.marks) {
return 0;
}
return null;
}
}
2. Maintenant, vous pouvez appeler la méthode compareTo
à l'intérieur de la méthode sort
.
void _sortStudents({bool reversed: false}) {
_students.sort((a, b) {
return a.compareTo(b);
});
if (reversed) {
_students = _students.reversed.toList();
}
setState(() {});
}
Référez-vous à ce lien si vous voulez en savoir plus sur la classe Comparable
https://api.dart.dev/stable/2.1.0/dart-core/Comparable-class.html
En général, vous pouvez fournir une fonction de comparaison personnalisée à List.sort
.
/// Relation souhaitée | Résultat
/// -------------------------------------------
/// a < b | Renvoie une valeur négative.
/// a == b | Renvoie 0.
/// a > b | Renvoie une valeur positive.
///
int mySortComparison(SomeClass a, SomeClass b) {
final propertyA = someProperty(a);
final propertyB = someProperty(b);
if (propertyA < propertyB) {
return -1;
} else if (propertyA > propertyB) {
return 1;
} else {
return 0;
}
}
list.sort(mySortComparison);
Si vous triez une classe personnalisée que vous possédez, vous pouvez alternativement faire en sorte que votre classe implémente l'interface Comparable
:
class MyCustomClass implements Comparable {
...
@override
int compareTo(MyCustomClass other) {
if (someProperty < other.someProperty) {
return -1;
} else if (someProperty > other.someProperty) {
return 1;
} else {
return 0;
}
}
}
et ensuite vous pouvez utiliser list.sort()
directement sans fournir de rappel.
Remarquez que si vous triez par une seule propriété qui implémente déjà l'interface Comparable
, implémenter les fonctions de comparaison est beaucoup plus simple. Par exemple :
class MyCustomClass implements Comparable {
...
@override
int compareTo(MyCustomClass other) =>
someProperty.compareTo(other.someProperty);
}
Si vous souhaitez inverser l'ordre de tri, vous pouvez faire en sorte que votre fonction de comparaison renvoie une valeur avec le signe opposé. Alternativement, inversez explicitement la liste après le tri :
list = (list..sort()).reversed.toList();
Si vous souhaitez trier par plusieurs propriétés, une manière générale consiste à effectuer un tri stable pour chaque propriété dans l'ordre inverse de l'importance. Par exemple, si vous souhaitez trier les noms principalement par nom de famille et ensuite trier les prénoms au sein des noms de famille, vous trieriez d'abord par prénoms, puis effectueriez un tri stable par nom de famille. Voir ci-dessous comment effectuer un tri stable.
Alternativement, vous pourriez trier avec une fonction de comparaison qui tient compte de plusieurs propriétés. Par exemple :
class Name {
Name({String surname, String givenName})
: surname = surname ?? "",
givenName = givenName ?? "";
final String surname;
final String givenName;
}
int compareNames(Name name1, Name name2) {
var comparisonResult = name1.surname.compareTo(name2.surname);
if (comparisonResult != 0) {
return comparisonResult;
}
// Les noms de famille sont les mêmes, donc on trie par prénom.
return name1.givenName.compareTo(name2.givenName);
}
List.sort
n'est pas garanti d'être un tri stable. Si vous avez besoin d'un tri stable, le package:collection fournit des implémentations de insertionSort
et de mergeSort
qui sont stables.
Supposons que vous avez une fonction de comparaison personnalisée qui ressemble à ceci :
int compareMyCustomClass(MyCustomClass a, MyCustomClass b) {
var a0 = computeValue(a);
var b0 = computeValue(b);
return a0.compareTo(b0);
}
Le tri pourrait appeler computeValue()
sur chaque élément plusieurs fois, ce qui est particulièrement gaspilleur si computeValue()
est coûteux. Dans de tels cas, une transformée de Schwartzian pourrait être plus rapide (au détriment de l'utilisation de plus de mémoire). Cette approche mappe vos objets à des clés directement triables, trie les clés et extrait les objets d'origine. (C'est ainsi que fonctionnent les fonctions de tri et de tri de Python.)
Voici une implémentation possible :
class _SortableKeyPair>
implements Comparable<_SortableKeyPair> {
_SortableKeyPair(this.original, this.key);
final T original;
final K key;
@override
int compareTo(_SortableKeyPair other) => key.compareTo(other.key);
}
List sortedWithKey>(
Iterable items,
K Function(E) toKey,
) {
final keyPairs = [
for (var element in items) _SortableKeyPair(element, toKey(element)),
]..sort();
return [
for (var keyPair in keyPairs) keyPair.original,
];
}
void main() {
final list = [ ... ];
final sorted = sortedWithKeys(list, computeValue);
}
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
2 votes
Possible duplicate de Comment puis-je trier une liste de chaînes en Dart?
0 votes
@RichardHeap oui, la solution répond à ma question mais la question est posée différemment, je suppose. Merci pour votre aide!
1 votes
J'ai écrit une réponse ici stackoverflow.com/a/59350472/10409567