Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best/shortest way to convert an Iterable to a Stream, in Dart?

I have an Iterable, and I'd like to convert it to a Stream. What is the most efficient/shortest-amount-of-code to do this?

For example:

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...
}

Note: iterable.toStream() doesn't exist, but I want something like that. :)

like image 769
Seth Ladd Avatar asked Mar 31 '15 19:03

Seth Ladd


3 Answers

Here's a simple example:

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

Using your code:

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));
}
like image 189
w.brian Avatar answered Oct 20 '22 12:10

w.brian


In case you are using the Dart SDK version 1.9 or a newer one, you could easily create a stream using async*

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);
}

Maybe it is easier to read as it has less braces and "special" methods, but that is a matter of taste.

like image 43
Fox32 Avatar answered Oct 20 '22 11:10

Fox32


If you want to sequentially process each item in the iterable you can use 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))
}
like image 35
adam.lofts Avatar answered Oct 20 '22 10:10

adam.lofts