【问题标题】:Check whether a list contain an attribute of an object in dart检查列表是否包含飞镖中对象的属性
【发布时间】:2019-09-09 11:31:59
【问题描述】:

我需要检查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('Allready 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 不包含Strings;它包含MyItems。

标签: dart


【解决方案1】:

您使用的 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;

或者你可以遍历你的列表并以正常的方式一一搜索,这似乎稍微容易一些。

【讨论】:

    【解决方案2】:

    Contains() 比较整个对象。

    除了覆盖 == 操作符或循环,你还可以使用 list 的 singleWhere 方法:

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

    编辑: 正如 Dharaneshvar 所经历的和 cmets 中提到的 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 我想知道抛出那个的代码是什么。
    • 完全正确!这就是为什么我不推荐 .singleWhere() .. 而是推荐 firstWhere()。因为如果找到超过 1 个元素,它将抛出 StateError。但是 firstWhere() 只会返回该元素或执行 orElse: 代码块!
    • @YoApps 我更新了答案以反映何时使用 singleWhere 与 firstWhere
    【解决方案3】:

    如前所述, contains 使用 == 运算符比较两个对象。因此,您目前将MyItemString itemId 进行比较,这将永远不会相同。

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

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

    myItemsList.any((item) => item.itemId == myitem.itemId);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-02
      • 2012-05-24
      • 2019-06-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多