Как я могу сравнивать списки для равенства в Дарт?

Я сравниваю два списка в Dart следующим образом:

main() {
    if ([1,2,3] == [1,2,3]) {
        print("Equal");
    } else {
        print("Not equal");
    }   
}

Но они никогда не равны. Кажется, что нет равных() методов в Dart API для сравнения списков или коллекций. Есть ли способ сделать это?

Ответы

Ответ 1

Чтобы завершить ответ Gunter: рекомендуемый способ сравнения списков для равенства (а не идентификатора) заключается в использовании классов Equality из следующего пакета

import 'package:collection/collection.dart';

Изменить: до версии 1.13 это был пакет import: collection/equal.dart ';

например.

Function eq = const ListEquality().equals;
print(eq([1,'two',3], [1,'two',3])); // => true

Вышеприведенные выше true, поскольку соответствующие элементы списка identical(). Если вы хотите (глубоко) сравнить списки, которые могут содержать другие коллекции, вместо этого используйте:

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

Существуют другие классы Equality, которые можно комбинировать разными способами, включая равенство для Map s. Вы даже можете выполнить неупорядоченное (глубокое) сравнение коллекций:

Function unOrdDeepEq = const DeepCollectionEquality.unordered().equals;
List list3 = [3, [[],'a'], 1];
print(unOrdDeepEq(list2, list3)); // => true

Подробнее см. в документации по API пакета . Как обычно, для использования такого пакета вы должны перечислить его в своем pubspec.yaml:

dependencies:
  collection: any

Ответ 2

Коллекции в Dart не имеют внутреннего равенства. Два набора не равны, даже если они содержат точно такие же объекты, что и элементы.

Библиотека коллекции предоставляет методы для определения такого равенства. В этом случае, например

IterableEquality().equals([1,2,3],[1,2,3])

равенство, которое считает два списка точно равными, если они содержат идентичные элементы.

Ответ 3

Для тех, кто использует Flutter, он имеет встроенную функцию listEquals, которая сравнивает для глубокого равенства.

var list1 = [1, 2, 3];
var list2 = [1, 2, 3];

assert(listEquals<int>(list1, list2) == true);
var list1 = [1, 2, 3];
var list2 = [3, 2, 1];

assert(listEquals<int>(list1, list2) == false);

Ответ 4

Я просто наткнулся на это

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");
  }
}

подробнее https://github.com/dart-lang/bleeding_edge/tree/master/dart/pkg/collection

Ответ 5

Хотя этот вопрос довольно старый, эта функция все еще не приземлилась в Дарте. Мне нужно было провести глубокое сравнение равенства (List<List>), поэтому я теперь занял рекурсивный вызов:

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

Примечание: при смешивании типов коллекций (т.е. List<Map>) это все равно будет терпеть неудачу - он просто закрывает List<List<List>> и так далее.

Последняя проблема с дротиками на этом, кажется, https://code.google.com/p/dart/issues/detail?id=2217 (последнее обновление мая 2013 г.).

Ответ 6

Библиотека Built Collections предлагает неизменные коллекции для Dart, которые включают в себя равенство, хэширование и другие лакомства.

Если вы делаете что-то, что требует равенства, вам также будет лучше с неизменностью.

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

Ответ 7

Что-то вроде этой работы для вас?

try {
    Expect.listEquals(list1, list2);
  } catch (var e) {
    print("lists aren't equal: $e");
  }

Пример:

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");
  }
}

Вторые попытки печати:

Lists aren't equal: Expect.listEquals(list length, expected: <4>, actual: <5>) fails

Ответ 8

Прежде чем приступить к работе, вы можете использовать это:

  /**
   * 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;
    });
  }

Ответ 9

Другим вариантом является использование пакета "запросы".

import 'package:queries/collections.dart';

void main() {
  var list1 = [1, 2, 3];
  var list2 = [1, 2, 3];
  var col1 = new Collection(list1);
  var col2 = new Collection(list2);
  if (col1.sequenceEqual(col2)) {
    print("Lists equal");
  } else {
    print("Lists not equal");
  }
}

Функция sequenceEqual объявлена следующим образом:

bool sequenceEqual(IEnumerable<TSource> other,
      [IEqualityComparer<TSource> comparer])

Эта функция может использоваться для сравнения любых последовательностей данных. Также можно использовать пользовательский компаратор равенства данных. По умолчанию используются встроенные компараторы.

Ответ 10

Если у вас есть класс с полем списка, как

class A {
  final String name;
  final List<int> list;
  A(this.name, this.list);
}

и хотите сравнить его экземпляры, вы можете использовать экваториальный пакет

class A extends Equatable {
  final String name;
  final List<int> list;
  A(this.name, this.list) : super([name, list]);
}

а затем просто сравнить объекты, используя ==

final x = A('foo', [1,2,3]);
final y = A('foo', [1,2,3]);
print(x == y); // true