如何在Dart中比较列表中的相等性?

时间:2012-05-01 21:19:45

标签: dart

我正在比较Dart中的两个列表:

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

但他们永远不会平等。 Dart API中似乎没有equ()方法来比较列表或集合。有没有正确的方法来做到这一点?

14 个答案:

答案 0 :(得分:41)

完成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

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

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

有关详细信息,请参阅package API documentation。像往常一样,要使用此类软件包,您必须在pubspec.yaml

中列出
dependencies:
  collection: any

答案 1 :(得分:6)

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

collection library提供了定义这种相等性的方法。在这种情况下,为 示例

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

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

答案 2 :(得分: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

答案 3 :(得分:3)

虽然这个问题相当陈旧,但该功能仍未在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月)。

答案 4 :(得分:3)

对于使用Flutter的用户,它具有本机方法listEquals,该方法会进行深度平等的比较。

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

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

print(listEquals<int>(list1, list2));  // false

答案 5 :(得分:1)

Built Collections库为Dart提供了不可变的集合,包括相等,散列和其他好东西。

如果你正在做一些需要平等的事情,你也有可能在不变性方面做得更好。

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

答案 6 :(得分:1)

在Dart中比较int的两个列表是否相等的简单解决方案可以是使用join()将其与String进行比较:

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

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

答案 7 :(得分:0)

这样的事情对你有用吗?

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 :(得分:0)

在开始工作之前,你可以使用它:

  /**
   * 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 :(得分:0)

另一个选择是使用软件包“查询”。

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 :(得分:0)

如果您有一个带有列表字段的课程,例如

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

并想比较其实例,可以使用equatable package

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

答案 11 :(得分:0)

我使用https://issues.apache.org/jira/browse/AIRFLOW-2910函数比较列表,在不导入第三方库或不使用compareTo的情况下检查深度相等性也很有用:

List<List<int>> firstList = List.generate(9, (i) => List.generate(9, (j) => (9*i + j) )) ;

List<List<int>> secondList = List.generate(9, (i) => List.generate(9, (j) => (9*i + j) )) ;



bool compareLists( List<List<int>> one, List<List<int>> two){

    return one.toString().compareTo(two.toString()) == 0 ;

  }

print('Lists are ${compareLists(one, two) ? '' : 'not '} equal !');

答案 12 :(得分:-1)

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

void main() {
  var a = [1,2,3];
  var b = [1,3,2];
  
  var condition1 = a.toSet().difference(b.toSet()).length == 0;
  var condition2 = a.length == b.length;
  var isEqual = condition1 && condition2
  isEqual ? print(true) : print(false); // Will print true
}

答案 13 :(得分:-1)

最方便的选择是在 List 类上创建一个 extension method

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