Je compare deux listes dans Dart comme ceci:
main() {
if ([1,2,3] == [1,2,3]) {
print("Equal");
} else {
print("Not equal");
}
}
Mais ils ne sont jamais égaux. Il ne semble pas y avoir de méthode equal () dans l'API Dart pour comparer les listes ou les collections. Existe-t-il une bonne façon de procéder?
Pour compléter la réponse de Gunter: la méthode recommandée pour comparer les listes pour l'égalité (plutôt que pour l'identité) consiste à utiliser les classes d'égalité du package suivant
import 'package:collection/collection.Dart';
Edit : avant 1.13, c'était import 'package: collection/l'égalité.Dart';
Par exemple.,
Function eq = const ListEquality().equals;
print(eq([1,'two',3], [1,'two',3])); // => true
Ce qui précède affiche true
parce que les éléments de liste correspondants qui sont identical()
. Si vous souhaitez comparer (en profondeur) des listes qui pourraient contenir d'autres collections, utilisez plutôt:
Function deepEq = const DeepCollectionEquality().equals;
List list1 = [1, ['a',[]], 3];
List list2 = [1, ['a',[]], 3];
print( eq(list1, list2)); // => false
print(deepEq(list1, list2)); // => true
Il existe d'autres classes d'égalité qui peuvent être combinées de plusieurs manières, y compris l'égalité pour Map
s. Vous pouvez même effectuer une comparaison non ordonnée (approfondie) des collections:
Function unOrdDeepEq = const DeepCollectionEquality.unordered().equals;
List list3 = [3, [[],'a'], 1];
print(unOrdDeepEq(list2, list3)); // => true
Pour plus de détails, consultez la documentation de l'API du package . Comme d'habitude, pour utiliser un tel package, vous devez le répertorier dans votre pubspec.yaml
:
dependencies:
collection: any
Pour ceux qui utilisent Flutter, il a la fonction native listEquals
, qui compare pour une égalité profonde.
var list1 = <int>[1, 2, 3];
var list2 = <int>[1, 2, 3];
assert(listEquals(list1, list2) == true);
var list1 = <int>[1, 2, 3];
var list2 = <int>[3, 2, 1];
assert(listEquals(list1, list2) == false);
Les collections de Dart n'ont aucune égalité inhérente. Deux ensembles ne sont pas égaux, même s'ils contiennent exactement les mêmes objets que les éléments.
bibliothèque de collection fournit des méthodes pour définir une telle égalité. Dans ce cas, par exemple
IterableEquality().equals([1,2,3],[1,2,3])
est une égalité qui considère deux listes égales exactement si elles contiennent des éléments identiques.
Je suis juste tombé sur ça
import 'package:collection/equality.Dart';
void main(List<String> args) {
if (const IterableEquality().equals([1,2,3],[1,2,3])) {
// if (const SetEquality().equals([1,2,3].toSet(),[1,2,3].toSet())) {
print("Equal");
} else {
print("Not equal");
}
}
plus d'informations https://github.com/Dart-lang/bleeding_Edge/tree/master/Dart/pkg/collection
Bien que cette question soit assez ancienne, la fonctionnalité n'a toujours pas atterri de manière native dans Dart. J'avais besoin d'une comparaison approfondie de l'égalité (List<List>
), j'ai donc emprunté d'en haut maintenant avec un appel récursif:
bool _listsAreEqual(list1, list2) {
var i=-1;
return list1.every((val) {
i++;
if(val is List && list2[i] is List) return _listsAreEqual(val,list2[i]);
else return list2[i] == val;
});
}
Remarque: cela échouera toujours lors du mélange des types de collection (c'est-à-dire List<Map>
) - il ne couvre que List<List<List>>
etc.
Le dernier problème Dart à ce sujet semble être https://code.google.com/p/Dart/issues/detail?id=2217 (dernière mise à jour en mai 2013).
La bibliothèque Built Collections propose des collections immuables pour Dart qui incluent l'égalité, le hachage et d'autres goodies.
Si vous faites quelque chose qui nécessite l'égalité, il y a une chance que vous feriez mieux avec l'immuabilité aussi.
Quelque chose comme cela fonctionnerait-il pour vous?
try {
Expect.listEquals(list1, list2);
} catch (var e) {
print("lists aren't equal: $e");
}
Exemple:
main() {
List<int> list1 = [1, 2, 3, 4, 5];
List<int> list2 = new List.from(list1);
try {
Expect.listEquals(list1, list2);
} catch (var e) {
print("lists aren't equal: $e");
}
list1.removeLast();
try {
Expect.listEquals(list1, list2);
} catch (var e) {
print("Lists aren't equal: $e");
}
}
Deuxième essai d'impressions:
Lists aren't equal: Expect.listEquals(list length, expected: <4>, actual: <5>) fails
Je compare les listes en utilisant la fonction compareTo
, il est également utile de vérifier une profonde égalité sans importer de bibliothèques tierces ou en utilisant listEquals
:
List<List<int>> firstList = List.generate(9, (i) => List.generate(9, (j) => (9*i + j) )) ;
List<List<int>> secondList = List.generate(9, (i) => List.generate(9, (j) => (9*i + j) )) ;
bool compareLists( List<List<int>> one, List<List<int>> two){
return one.toString().compareTo(two.toString()) == 0 ;
}
print('Lists are ${compareLists(one, two) ? '' : 'not '} equal !');
Avant que les choses fonctionnent, vous pouvez utiliser ceci:
/**
* Returns true if the two given lists are equal.
*/
bool _listsAreEqual(List one, List two) {
var i = -1;
return one.every((element) {
i++;
return two[i] == element;
});
}
Si vous avez une classe avec un champ de liste, comme
class A {
final String name;
final List<int> list;
A(this.name, this.list);
}
et que vous souhaitez comparer ses instances, vous pouvez utiliser package équitable
class A extends Equatable {
final String name;
final List<int> list;
A(this.name, this.list) : super([name, list]);
}
puis comparez simplement les objets à l'aide de ==
final x = A('foo', [1,2,3]);
final y = A('foo', [1,2,3]);
print(x == y); // true