2017-06-01 61 views
2

forEach作品就好爲什麼地圖不能正常工作,但是foreach是?

var newMarkers = new List<Marker>(); 
providers.forEach((p) { 
    var marker = markerFrom(p); 
    newMarkers.add(marker); 
    print("got one"); 
}); 

_markers = newMarkers; 

但這map並放置在相同的位置作爲forEach時都不曾呼籲:

_markers = providers.map((p) => markerFrom(p)); 

此外,這是markerFrom方法:

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; 
} 
+0

你有任何錯誤訊息?如果你想操作'List ','map'會產生'Iterable',所以你必須做'_markers = providers.map((p)=> markerFrom(p))。toList() ;',但這取決於你想用'_markers'做什麼 –

回答

5

The 上的功能是懶惰。它只是創建一個包裝原始Iterable,但它實際上沒有做任何事情,直到你開始迭代。

這是一個好東西,即使您習慣於從其他語言的渴望map功能可能會令人驚訝。這意味着您可以將迭代操作合併爲:

listOfStrings 
    .map((x) => complicatedOperationOnString(x)) 
    .take(2) 
    .forEach(print); 

這隻對前兩個字符串執行復雜的操作。

如果你想標記的列表,你需要map之後調用toList

_markers = providers.map(markerFrom).toList(); 

在一般情況下,你應該非常小心,當傳遞給map的功能有副作用,你想只發生一次。如果你迭代不止一次map更多的結果,效果會每次都發生,因此,如果你做的事:

_markers = providers.map(markerFrom); 
int count = _markers.length; 
_markers.forEach((marker) { doSomething(marker); }); 

你會風險的副作用forEach發生兩次,一次用於length有一次,這兩者迭代_markers。它並不總是發生(有些迭代器知道他們的length沒有實際迭代),但它總是風險。在這些情況下,如果副作用是您以後唯一的情況,請使用forEach,或者立即執行toList來強制執行所有操作,然後再查看結果列表。