如何比较达特中的列表是否相等?

我用 Dart 比较了两个列表:

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

但他们从不平等。在 Dart API 中似乎没有 equal()方法来比较列表或集合。有什么合适的方法吗?

106164 次浏览

收藏在达特没有固有的平等。两个集合不相等,即使它们包含与元素完全相同的对象。

藏书图书馆提供了定义这种等式的方法 例子

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

是一个等式,它认为两个包含相同元素的列表完全相等。

你觉得这样行吗?

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

在工作之前,你可以这样做:

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

虽然这个问题已经很老了,但是这个特性还没有在 Dart 中实现。我需要进行深度相等比较(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;
});
}

注意: 当混合 Collection 类型(即 List<Map>)时仍然会失败-它只覆盖 List<List<List>>等等。

最新的飞镖问题,这似乎是 https://code.google.com/p/dart/issues/detail?id=2217(最后更新2013年5月)。

我无意中发现了这个

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

更多信息

为了完成 Gunter 的回答: 比较相等列表(而不是标识)的推荐方法是使用下面包中的相等类

import 'package:collection/collection.dart';

编辑 : 在1.13之前,它是 < del > import‘ package: Collection/equality.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

还有其他可以以多种方式组合的等式类,包括 Map的等式。您甚至可以执行集合的 无序(深度)比较:

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

有关详细信息,请参阅 包 API 文档。像往常一样,要使用这样的软件包,您必须在您的 pubspec.yaml中列出它:

dependencies:
collection: any

构建的集合库为 Dart 提供了不可变的集合,其中包括相等、散列和其他优点。

如果你正在做的事情需要平等,有一个机会,你会更好地与不变性,也。

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

有时,人们不想比较列表本身,而是想比较包含列表的一些对象(类实例)

让你有一个带列表字段的类,比如

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

@override
List<Object> get props => [name, list];
}

然后简单地使用 ==比较对象

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

对于那些使用 Flutter 的用户,它具有本机函数 listEquals,它可以进行深度相等性比较。

import 'package:flutter/foundation.dart';


var list1 = <int>[1, 2, 3];
var list2 = <int>[1, 2, 3];


assert(listEquals(list1, list2) == true);
import 'package:flutter/foundation.dart';


var list1 = <int>[1, 2, 3];
var list2 = <int>[3, 2, 1];


assert(listEquals(list1, list2) == false);

请注意,根据文件记录:

上面的术语“ deep”指的是第一个相等级别: 如果元素是映射、列表、集合或其他集合/组合对象,那么这些元素的值不会逐个元素进行比较,除非它们的相等操作符(Object.operator==)这样做。

因此,如果您正在寻找无限级别的相等,请查看 DeepCollectionEquality,正如 帕特里斯 · 查林所建议的那样。

另外,如果您需要针对不同集合的这些特性,还有 setEqualsmapEquals

对于 Dart 中的 比较两个 int 列表的相等性,一个简单的解决方案是使用 join ()将其作为 String 进行比较:

var a = [1,2,3,0];
var b = [1,2,3,4];


a.join('') == b.join('') ? return true: return false;

在 Dart 中比较两个 int 列表相等性的一个简单解决方案是使用 Set (不检查列表中元素的顺序) :

void main() {
var a = [1,2,3];
var b = [1,3,2];
  

var condition1 = a.toSet().difference(b.toSet()).isEmpty;
var condition2 = a.length == b.length;
var isEqual = condition1 && condition2;
print(isEqual); // Will print true
}

最方便的选择是在 List类上创建 推广方法推广方法

extension on List {
bool equals(List list) {
if(this.length!=list.length) return false;
return this.every((item) => list.contains(item));
}
}

上面的代码所做的是检查第一个列表(this)中的每个 item是否包含在第二个列表(list)中。但是,这只有在两个列表长度相同的情况下才有效。无论如何,要使用这个扩展,这样做:

List list1, list2
list1.equals(list2);
bool areListsEqual(var list1, var list2) {
// check if both are lists
if(!(list1 is List && list2 is List)
// check if both have same length
|| list1.length!=list2.length) {
return false;
}
     

// check if elements are equal
for(int i=0;i<list1.length;i++) {
if(list1[i]!=list2[i]) {
return false;
}
}
     

return true;
}

现在可以使用内置的 listEquals、 setEquals 和 mapEquals 函数检查是否相等。

这是文档的链接: https://api.flutter.dev/flutter/foundation/listEquals.html