Как я могу сравнивать списки для равенства в Дарт?
Я сравниваю два списка в 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