#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) {}