如何在 Dart 中比较列表是否相等?

问题描述 投票:0回答:15

我正在比较 Dart 中的两个列表,如下所示:

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

但它们永远不平等。 Dart API 中似乎没有

equal()
方法来比较列表或集合。有没有正确的方法来做到这一点?

list dart equality
15个回答
272
投票

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

201
投票

对于那些使用 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==
)这样做。

因此,如果您正在寻找无限级别的平等,请查看

DeepCollectionEquality
,如Patrice Chalin所建议。

此外,如果您需要针对不同集合的此类功能,还有

setEquals
mapEquals


23
投票

Dart 中的集合没有固有的相等性。两个集合并不相等,即使它们包含与元素完全相同的对象。

集合库提供了定义这种等式的方法。在这种情况下,对于 例子

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

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


10
投票

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

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


9
投票

我只是偶然发现了这个

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


6
投票

在 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
}

5
投票

虽然这个问题相当老了,但该功能仍然没有在 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 月)。


3
投票

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

如果你正在做一些需要平等的事情,那么不变性也可能会更好。

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


3
投票

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

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

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

2
投票

最方便的选择是在 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);

1
投票

在工作之前,你可以使用这个:

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

1
投票

这样的东西对你有用吗?

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

1
投票
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;
}

0
投票

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

var a = [1,2,3,0]; var b = [1,2,3,4]; a.join('') == b.join('') ? return true: return false;
    

0
投票
给出了很多真实的答案,并且也接受了最好的答案之一。

这里我创建了一个方法,它接受两个列表{无论列表的类型(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; } }
    
© www.soinside.com 2019 - 2024. All rights reserved.