次のように、Dart で 2 つのリストを比較しています。
main() {
if ([1,2,3] == [1,2,3]) {
print("Equal");
} else {
print("Not equal");
}
}
しかし、それらは決して平等ではありません。Dart API には、リストまたはコレクションを比較する equal() メソッドがないようです。これを行う適切な方法はありますか?
次のように、Dart で 2 つのリストを比較しています。
main() {
if ([1,2,3] == [1,2,3]) {
print("Equal");
} else {
print("Not equal");
}
}
しかし、それらは決して平等ではありません。Dart API には、リストまたはコレクションを比較する equal() メソッドがないようです。これを行う適切な方法はありますか?
Gunter の回答を完成させるには: リストを (ID ではなく) 等しいかどうか比較するための推奨される方法は、次のパッケージの 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
s の等価性など、さまざまな方法で組み合わせることができる他の等価性クラスがありますMap
。コレクションの順序付けられていない(深い) 比較を実行することもできます。
Function unOrdDeepEq = const DeepCollectionEquality.unordered().equals;
List list3 = [3, [[],'a'], 1];
print(unOrdDeepEq(list2, list3)); // => true
詳細については、パッケージ API ドキュメントを参照してください。通常どおり、このようなパッケージを使用するには、次のようにリストする必要がありますpubspec.yaml
。
dependencies:
collection: any
Dart のコレクションには固有の等価性はありません。要素としてまったく同じオブジェクトが含まれていても、2 つのセットは等しくありません。
コレクション ライブラリは、そのような等価性を定義するメソッドを提供します。この場合、例えば
IterableEquality().equals([1,2,3],[1,2,3])
は、2 つのリストが同一の要素を含んでいる場合にそれらが完全に等しいと見なす等式です。
私はちょうどこれにつまずいた
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;
});
}
注: Collection タイプ (つまり ) を混在させると、これはまだ失敗しますList<Map>
- カバーするだけList<List<List>>
です。
これに関する最新の dart の問題はhttps://code.google.com/p/dart/issues/detail?id=2217 (2013 年 5 月の最終更新) のようです。
Built Collections ライブラリは、等価性、ハッシュ、およびその他の優れた機能を含む、Dart 用の不変のコレクションを提供します。
平等を必要とする何かをしているなら、不変性の方が良い可能性もあります。
Dart で int の 2 つのリストの等価性を比較する簡単な解決策は、セットを使用することです (リスト内の要素の順序をチェックせずに) :
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
}
リスト自体ではなく、リストを含むいくつかのオブジェクト (クラス インスタンス) を比較したい場合があります。
次のようなリストフィールドを持つクラスを用意しましょう
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
このようなものはあなたのために働くでしょうか?
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");
}
}
2 回目の試行の印刷:
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;
});
}