collection icon indicating copy to clipboard operation
collection copied to clipboard

Add alternateWith extension method on Iterable

Open alexeyinkin opened this issue 2 years ago • 1 comments

There is a repeating feature request in Flutter to add separators for children of Row and Column: https://github.com/flutter/flutter/issues/16957 https://github.com/flutter/flutter/issues/18917 https://github.com/flutter/flutter/issues/55378 https://github.com/flutter/flutter/issues/95263 https://github.com/flutter/flutter/issues/95521

At its highest it got 117 thumbs-ups. But it is declined over and over again because it can be solved outside of the framework with a few lines of code:

Iterable<T> alternateWith(Iterable<T> items, T separator) {
  return items
      .expand((item) sync* { yield separator; yield item; })
      .skip(1);
}

Can we add it to this package as an extension on Iterable? One could then do:

Column(
  children: <Widget>[
    Widget1(),
    Widget2(),
  ].alternateWith(separator).toList(),
),

One could easily make another package with this, as there are many. Yet they are unknown and may be poorly maintained. This package is widely used, endorsed, and can be referred to in Flutter docs thus ending the recurrance of the feature request or speeding up the debate should it occur again.

I can do it myself if approved.

alexeyinkin avatar Dec 21 '21 06:12 alexeyinkin

This is equivalent to https://github.com/dart-lang/sdk/issues/49900.

The biggest problem is the typing. We can create an extension method like:

extension X<T> on Iterable<T> {
  Iterable<T> intersperse(T separator, {bool beforeFirst = false, bool afterLast = false}) sync* {
    bool empty = true;
    for (var e in this) {
      if (!empty || beforeFirst) yield separator;
      empty = false;
      yield e;
    }
    if (!empty && afterLast) yield separator;
  }
}

The problem is that if you have a [ButtonWidget(...), ButtonWidget(...)].intersperse(SpacerWidget(...), it won't work. You have to write <Widget>[ButtonWidget(...), ButtonWidget(...)].intersperse(SpacerWidget(...). (If only we could write Iterable<S> intersperse<S super T>(S separator, ...).)

lrhn avatar Sep 09 '22 12:09 lrhn