Проверка, содержит ли список атрибут объекта в dart

#dart

#flutter #dart

Вопрос:

Мне нужно проверить, 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,
  });
}
 

приведенный выше код работает не так, как ожидалось, пожалуйста, помогите мне разобраться в проблеме.

Комментарии:

1. Вы вызываете myItemsList.contains(String) , но myItemsList не содержит String s; он содержит MyItem s.

Ответ №1:

Contains() сравнивает целые объекты.

Помимо переопределения оператора == или перебора, вы можете использовать метод singleWhere от list:

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

Редактировать:
Как было отмечено в опыте Dharaneshvar и YoApps в комментариях .singleWhere вызывает ошибку состояния при обнаружении большего количества элементов.

Это желательно, когда вы ожидаете уникальных элементов, например, в случае сравнения идентификаторов.

Возникшая ошибка здесь является другом, поскольку она показывает, что с данными что-то не так.

Для других случаев .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!');
  }
}
 

Комментарии:

1. Недавно получил сообщение «Плохое состояние: ошибка слишком большого количества элементов» во Flutter после обновления. Нужно ли внести какие-либо изменения или есть какой-либо альтернативный способ выполнить эту проверку?

2. @Dharaneshvar Интересно, что это за код, который выдает это.

3. ТОЧНО! Вот почему я бы НЕ рекомендовал .singleWhere() .. но вместо этого firstWhere() . Потому что, если найдено более 1 элемента, он выдаст StateError. Но firstWhere() просто вернет вам этот элемент или выполнит блок кода OrElse:!

4. @YoApps Я обновил ответ, чтобы отразить, когда использовать singleWhere против firstWhere

Ответ №2:

Как уже было сказано ранее, contains сравнивает два объекта с помощью оператора == . Итак, вы в настоящее время сравниваете MyItem с String itemId , который никогда не будет прежним.

Чтобы проверить, содержит ли myItemsList myitem.ItemId, вы можете использовать одно из следующих действий:

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

или

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

Ответ №3:

Вы используете 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 amp;amp; other.value == value;
 

Или вы можете перебирать свой список и выполнять поиск обычным способом один за другим, что кажется немного проще.

Ответ №4:

Еще один способ проверить, содержит ли список объект со свойством или нет

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