2015-03-31 88 views
7

我有一個Iterable,我想將它轉換爲Stream。什麼是最有效/最短的代碼量來做到這一點?Dart中將Iterable轉換爲Stream的最佳/最短途徑是什麼?

例如:

Future convert(thing) { 
    return someAsyncOperation(thing); 
} 

Stream doStuff(Iterable things) { 
    return things 
    .map((t) async => await convert(t)) // this isn't exactly what I want 
             // because this returns the Future 
             // and not the value 
    .where((value) => value != null) 
    .toStream(); // this doesn't exist... 
} 

注:iterable.toStream()不存在,但我想這樣的事情。 :)

+1

的'。凡(...)'部分不能因爲異步函數(閉包傳遞到'工作.map(...)')總是返回一個未來,因此即使'thing'爲null,'.where(...)'中的比較也總是爲真。 – 2015-03-31 20:26:14

回答

6

這裏有一個簡單的例子:

var data = [1,2,3,4,5]; // some sample data 
var stream = new Stream.fromIterable(data); 

使用代碼:

Future convert(thing) { 
    return someAsyncOperation(thing); 
} 

Stream doStuff(Iterable things) { 
    return new Stream.fromIterable(things 
    .map((t) async => await convert(t)) 
    .where((value) => value != null)); 
} 
+0

這不會返回一個期貨流而不是價值本身嗎? – Fox32 2015-03-31 21:23:32

+0

是的,但是如果存在假想的'toStream'方法,Seth的原始示例也是如此。不知道這是否是他的意圖,但最終問題是將「Iterable」轉換爲「Stream」的最佳方式。 – 2015-04-01 01:55:20

3

在您使用DART SDK 1.9版或更新一個情況下,你可以很容易地創建使用異步流*

import 'dart:async'; 

Future convert(thing) { 
    return new Future.value(thing); 
} 

Stream doStuff(Iterable things) async* { 
    for (var t in things) { 
    var r = await convert(t); 

    if (r != null) { 
     yield r; 
    } 
    } 
} 

void main() { 
    doStuff([1, 2, 3, null, 4, 5]).listen(print); 
} 

也許這是更容易重新因爲它具有較少的大括號和「特殊」方法,但這是一個品味問題。

+0

這就是我最終做的。謝謝! – 2015-04-01 03:47:41

1

如果要依次地處理每個項目的迭代,你可以使用Stream.asyncMap

Future convert(thing) { 
    return waitForIt(thing); // async operation 
} 

f() { 
    var data = [1,2,3,4,5]; 
    new Stream.fromIterable(data) 
    .asyncMap(convert) 
    .where((value) => value != null)) 
} 
相關問題