web-dev-qa-db-fra.com

Comment comparer les listes d'égalité dans Dart?

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?

43
Mark B

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 Maps. 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
58
Patrice Chalin

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);
39
Hugo Passos

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.

9
Lars Tackmann

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

5
Günter Zöchbauer

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).

3
RealBlueSky

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.

http://www.dartdocs.org/documentation/built_collection/0.3.1/index.html#built_collection/built_collection

1
David Morgan

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
0
scribeGriff

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 !');
0
Mazin Ibrahim

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;
    });
  }
0
Tower

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
0
Pavel