问题
This forEach
works just fine
var newMarkers = new List<Marker>();
providers.forEach((p) {
var marker = markerFrom(p);
newMarkers.add(marker);
print("got one");
});
_markers = newMarkers;
but this map
doesn't ever get called when placed in the exact same place as the forEach
:
_markers = providers.map((p) => markerFrom(p));
Additionally, this is the markerFrom
method:
Marker markerFrom(FoodProvider provider) {
var marker = new Marker(new MarkerOptions()
..map = _map
..position = new LatLng(provider.latitude, provider.longitude)
..title = provider.name
..icon = 'http://maps.google.com/mapfiles/ms/icons/red-dot.png'
);
var infoWindow = new InfoWindow(new InfoWindowOptions()..content = marker.title);
marker.onClick.listen((e) {
infoWindow.open(_map, marker);
});
return marker;
}
回答1:
The map
function on Iterable
is lazy. It just creates a wrapper around the original Iterable
, but it doesn't actually do anything until you start iterating.
That's a good thing, even if it can be surprising if you are used to an eager map
function from other languages. It means that you can combine operations on iterables like:
listOfStrings
.map((x) => complicatedOperationOnString(x))
.take(2)
.forEach(print);
This only does the complicated operation on the first two strings.
If you want a list of the markers, you need to call toList
after the map
:
_markers = providers.map(markerFrom).toList();
In general, you should be very careful when the function passed to map
has side-effects that you want to only happen once. If you iterate the result of map
more than once, that effect will happen each time, so if you did:
_markers = providers.map(markerFrom);
int count = _markers.length;
_markers.forEach((marker) { doSomething(marker); });
you would risk the side effects happening twice, once for length
and once for forEach
, which both iterate _markers
.
It doesn't always happen (some iterables know their length
without actually iterating), but it is always a risk. In those cases, either use forEach
if the side-effect is the only thing you are after, or do an immediate toList
to force all the operations, and then only look at the resulting list after that.
来源:https://stackoverflow.com/questions/44299842/why-is-map-not-working-but-foreach-is