我正在比较 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之前,是 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
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==
DeepCollectionEquality
,如Patrice Chalin所建议。
setEquals
和 mapEquals
。
Dart 中的集合没有固有的相等性。两个集合并不相等,即使它们包含与元素完全相同的对象。
集合库提供了定义这种等式的方法。在这种情况下,对于 例子
IterableEquality().equals([1,2,3],[1,2,3])
是一个等式,如果两个列表包含相同的元素,则认为它们完全相等。
您现在可以使用内置的 listEquals、setEquals 和 mapEquals 函数来检查是否相等。
这是文档的链接:https://api.flutter.dev/flutter/foundation/listEquals.html
我只是偶然发现了这个
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 中比较两个 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;
print(isEqual); // Will print true
}
虽然这个问题相当老了,但该功能仍然没有在 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>>
等等。
最新的 dart 问题似乎是 https://code.google.com/p/dart/issues/detail?id=2217(最后更新于 2013 年 5 月)。
Built Collections 库为 Dart 提供了不可变的集合,其中包括相等性、散列和其他好处。
如果你正在做一些需要平等的事情,那么不变性也可能会更好。
有时,人们想要比较的不是列表本身,而是一些包含列表的对象(类实例)
让你有一个带有列表字段的类,比如
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
最方便的选择是在 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);
在工作之前,你可以使用这个:
/**
* 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;
});
}
这样的东西对你有用吗?
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
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;
}
在 Dart 中比较两个 int 列表的相等性的一个简单解决方案是使用 join() 将其作为 String 进行比较:
var a = [1,2,3,0];
var b = [1,2,3,4];
a.join('') == b.join('') ? return true: return false;
这里我创建了一个方法,它接受两个列表{无论列表的类型(int,double,String)}并给出bool返回值。
带有示例的完整代码
void main() {
List x = [1, 2, 3];
List y = [2, 3, 1];
bool success = isTwoListAreSame(x, y);
print('=> $success'); // true
List x2 = ["A", "B", "C"];
List y2 = ["P", "Q", "R"];
bool success2 = isTwoListAreSame(x2, y2);
print('=> $success2'); // false
List x3 = ["A", "B", "C"];
List y3 = ["A", "B"];
bool success3 = isTwoListAreSame(x3, y3);
print('=> $success3'); // false
}
方法
/// this method made for only same length of list
/// no matter elements of list are in order or not.
bool isTwoListAreSame(List list1, List list2) {
// if both list are empty
// then no need no compare
// return true directly
if (list1.isEmpty && list2.isEmpty) {
return true;
} else if (list1.length == list2.length) {
// if both list have equal length
// take first list every element and compare with second list every element
// if all element are same it will return true
final bool isSame = list1.every(
(e1) {
return list2.any(
(e2) {
return e1 == e2;
},
);
},
);
return isSame;
} else {
// when both list are not equal length
return false;
}
}