#flutter #dart
#флаттер #dart
Вопрос:
Я извлекаю a querysnapshot
из Firestore, который возвращает список querydocumentsnapshot с snapshot.docs, но когда я пытаюсь сопоставить его, ничего не происходит. Если я использую for...in
цикл, он работает отлично.
QuerySnapshot snap =
await FirebaseFirestore.instance.collection('Products').doc(FirebaseAuth.instance.currentUser.uid).collection('ItemDetails').get();
print(snap.docs);//returns [Instance of 'QueryDocumentSnapshot', Instance of 'QueryDocumentSnapshot', Instance of 'QueryDocumentSnapshot']
for (var item in snap.docs.toList()) {//this executes perfectly
print(item.data());
}
snap.docs.toList().map((e) => print(e.data().toString()));//this won't execute
snap.docs.map((e) => print(e.data().toString()));//this won't execute
Почему .map()
не работает, когда for
цикл выполняется?
Комментарии:
1. Если вы не собираетесь использовать результат
List.map
, тогдаList.forEach
илиfor
цикл будет более подходящим. Смысл использованияList.map
заключается в создании новогоList
.
Ответ №1:
Это связано с тем, как map
работает метод. Согласно документации —
метод map<T>
Iterable<T> map <T>( T f( E e ) )
Возвращает новую отложенную итерацию с элементами, которые создаются путем вызова
f для каждого элемента этой итерации в порядке итерации.Этот метод возвращает представление отображенных элементов. До тех пор, пока возвращаемый итерируемый объект не будет повторен, предоставленная функция f не будет вызвана. Преобразованные элементы не будут кэшироваться. Многократное повторение возвращаемой итерации приведет к вызову предоставленной функции f несколько раз для одного и того же элемента.
Методам возвращаемой итерации разрешено не вызывать f для любого элемента, где результат не нужен. Например, ElementAt может вызвать f только один раз.
В вашем примере, поскольку вы не выполняете итерацию по результату Iterable
, он не вызовет функцию. Так что, если вы измените свой код на это
snap.docs.map((e) => print(e.data().toString())).toList();
затем он будет выполнен, потому что теперь ему нужно выполнить итерацию по результату Iterable
, чтобы преобразовать его в a List
.
Ответ №2:
List.map создает итерацию, но фактически не выполняет итерацию по ней. Вы можете увидеть это в этом примере:
List<String> s = ["a", "b", "c"];
var i = s.map((e){
print(e);
});
i.toList(); //prints a, b, c
Вы можете принудительно вызвать его, вызвав .ToList() вот так:
List<String> s = ["a", "b", "c"];
var i = s.map((e){
print(e);
}).toList(); //prints a,b,c
print(i.length); //3
Комментарии:
1. Спасибо, ваши примеры помогли мне лучше понять проблему