在Dart中检查列表是否包含对象的属性

25

我需要检查myItemsList是否包含myitem.itemId,如果存在,则需要添加itemQuantity,如果不存在,则需要将myitem对象添加到myItemsList

List<MyItem> myItemsList = new List();

MyItem myitem = new MyItem (
  itemId: id,
  itemName: name,
  itemQuantity: qty,
);

if (myItemsList.contains(myitem.itemId)) {
  print('Already exists!');
} else {
  print('Added!');
  setState(() {
    myItemsList.add(myitem);
  });
}

MyItem

class MyItem {
  final String itemId;
  final String itemName;
  int itemQuantity;

  MyItem ({
    this.itemId,
    this.itemName,
    this.itemQuantity,
  });
}

以上代码没有按预期工作,请帮助我找出问题所在。


你正在调用 myItemsList.contains(String),但是 myItemsList 不包含 String,它包含的是 MyItem - jamesdlin
4个回答

37

如前所述,contains使用==运算符比较两个对象。所以您当前正在比较MyItemString itemId,它们永远不会相同。

要检查myItemsList是否包含myitem.itemId,可以使用以下方法之一:

myItemsList.map((item) => item.itemId).contains(myitem.itemId);
或者
myItemsList.any((item) => item.itemId == myitem.itemId);

29

Contains()方法比较整个对象。

除了重写==运算符或循环遍历,您还可以使用列表的singleWhere()方法:

  if ((myItemsList.singleWhere((it) => it.itemId == myitem.itemId,
          orElse: () => null)) != null) {

编辑: 正如Dharaneshvar所经历的和YoApps在评论中提到的,当找到更多元素时,singleWhere会引发StateError。

如果您期望唯一元素(例如在比较ID的情况下),那么这是期望的结果。

引发的错误是友好的,因为它表明数据存在问题。

对于其他情况,请使用.firstWhere()方法:

  if ((myItemsList.firstWhere((it) => it.itemName == myitem.itemName,
          orElse: () => null)) != null) {

// EO 编辑

整个示例:

List<MyItem> myItemsList = new List();
​
class MyItem {
  final String itemId;
  final String itemName;
  int itemQuantity;
​
  MyItem({
    this.itemId,
    this.itemName,
    this.itemQuantity,
  });
}
​
void main() {
  MyItem myitem = new MyItem(
    itemId: "id00",
    itemName: "name",
    itemQuantity: 50,
  );
​
  myItemsList.add(myitem);
​
  String idToCheck = "id00";
​
  if ((myItemsList.singleWhere((it) => it.itemId == idToCheck,
          orElse: () => null)) != null) {
    
    print('Already exists!');
  } else {
    print('Added!');
  }
}

最近在Flutter升级后出现了“Bad State: too many elements error”的错误。是否有任何更改需要进行或者有其他替代方法来进行此检查? - Dharaneshvar
@Dharaneshvar 我在想是哪段代码引起了这个问题。 - Radek
没错!这就是为什么我不建议使用 **.singleWhere()**,而是使用 **firstWhere()**。因为如果找到多个元素,它会抛出 StateError。但是 firstWhere() 只会返回该元素或执行 orElse: 代码块! - Yo Apps
1
@YoApps 我更新了答案,以反映何时使用 singleWhere 和 firstWhere。 - Radek

11

你在使用contains方法时有些错误。

参考链接: https://api.dartlang.org/stable/2.2.0/dart-core/Iterable/contains.html

bool contains(Object element) {
  for (E e in this) {
    if (e == element) return true;
  }
  return false;
}

您可以覆盖==运算符,参见:https://dart-lang.github.io/linter/lints/hash_and_equals.html

@override    
bool operator ==(Object other) => other is Better && other.value == value;

或者你可以循环遍历你的列表,逐个进行正常搜索,这似乎更容易些。


1

检查列表中是否包含具有属性的对象的另一种方法

if (myList.firstWhereOrNull((val) => val.id == someItem.id) != null) {}

1
在使用 firstWhereOrNull 时,请确保添加以下导入语句: import 'package:collection/collection.dart'; - Rens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接