我正在像这样比较 Dart 中的两个列表:
main() {
if ([1,2,3] == [1,2,3]) {
print("Equal");
} else {
print("Not equal");
}
}
但他们从来都不是平等的。Dart API 中似乎没有用于比较列表或集合的 equal() 方法。有没有合适的方法来做到这一点?
我正在像这样比较 Dart 中的两个列表:
main() {
if ([1,2,3] == [1,2,3]) {
print("Equal");
} else {
print("Not equal");
}
}
但他们从来都不是平等的。Dart API 中似乎没有用于比较列表或集合的 equal() 方法。有没有合适的方法来做到这一点?
要完成 Gunter 的回答:比较列表是否相等(而不是身份)的推荐方法是使用以下包中的 Equality 类
import 'package:collection/collection.dart';
编辑:在 1.13 之前,它是导入'包: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
还有其他 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
对于那些使用 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);
请注意,根据文档:
上面的术语“深度”指的是第一级相等:如果元素是映射、列表、集合或其他集合/复合对象,那么这些元素的值不会逐个元素进行比较,除非它们的相等运算符 (
Object.operator==
)所以。
因此,如果您正在寻找无限级别的平等,请查看Patrice ChalinDeepCollectionEquality
的建议。
Dart 中的集合没有内在的相等性。两个集合不相等,即使它们包含与元素完全相同的对象。
集合库提供了定义这种相等性的方法。在这种情况下,例如
IterableEquality().equals([1,2,3],[1,2,3])
是一个相等性,如果两个列表包含相同的元素,则认为它们完全相等。
我只是偶然发现了这个
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
虽然这个问题已经相当老了,但该功能还没有在 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;
});
}
注意:混合集合类型(即List<Map>
)时这仍然会失败 - 它只是覆盖List<List<List>>
等等。
最新的飞镖问题似乎是https://code.google.com/p/dart/issues/detail?id=2217(最后更新于 2013 年 5 月)。
Built Collections 库为 Dart 提供了不可变的集合,包括相等、散列和其他好东西。
如果您正在做一些需要平等的事情,那么您也有可能在不变性方面做得更好。
最方便的选择是在类上创建一个扩展方法List
。
extension on List {
bool equals(List list) {
if(this.length!=list.length) return false;
return this.every((item) => list.contains(item));
}
}
上面的代码所做的是检查第一个列表 ( ) 中的每个单曲item
是否this
包含在第二个列表 ( list
) 中。但是,这仅适用于两个列表长度相同的情况。当然,您可以替换为其他解决方案之一或修改此解决方案,我只是为了方便起见。无论如何,要使用此扩展程序,请执行以下操作:
List list1, list2
list1.equals(list2);
有时想要比较的不是列表本身,而是包含列表的一些对象(类实例)
让你有一个带有列表字段的类,比如
class A {
final String name;
final List<int> list;
A(this.name, this.list);
}
并想比较它的实例,你可以使用equatable 包
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
在 Dart 中比较两个 int 列表是否相等的简单解决方案是使用 Sets(不检查列表中元素的顺序):
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;
isEqual ? print(true) : print(false); // Will print true
}
像这样的东西对你有用吗?
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 中比较两个 int 列表是否相等的简单解决方案是使用 join() 将其作为 String 进行比较:
var a = [1,2,3,0];
var b = [1,2,3,4];
a.join('') == b.join('') ? return true: return false;
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;
}