dart-lang / collection

The collection package for Dart contains a number of separate libraries with utility functions and classes that makes working with collections easier.
https://pub.dev/packages/collection
BSD 3-Clause "New" or "Revised" License
372 stars 86 forks source link

Add type safe `IterableZip` #341

Open narumincho opened 4 months ago

narumincho commented 4 months ago
import 'dart:collection';
import 'package:collection/collection.dart';

void main() {
  final listA = [0, 1, 2];
  final listB = ['aaa', 'bbb', 'ccc'];

  final zipped = IterableZip([listA, listB]);
  for (final [valueAsInt, valueAsString] in zipped) {
    print(valueAsString.substring(valueAsInt)); // type error. (The method 'substring' isn't defined for the type 'Object'.)
  }

  final zipped2 = IterableZip2(listA, listB);
  for (final (valueAsInt, valueAsString) in zipped2) {
    print(valueAsString.substring(valueAsInt)); // no type error. (output aaa, bb, c)
  }
}

Implementation Example

import 'dart:collection';

class IterableZip2<T, U> extends IterableBase<(T, U)> {
  final Iterable<T> _iterablesT;
  final Iterable<U> _iterablesU;

  IterableZip2(Iterable<T> iterablesT, Iterable<U> iterablesU)
      : _iterablesT = iterablesT,
        _iterablesU = iterablesU;

  @override
  Iterator<(T, U)> get iterator {
    return _IteratorZip2<T, U>(_iterablesT.iterator, _iterablesU.iterator);
  }
}

class _IteratorZip2<T, U> implements Iterator<(T, U)> {
  final Iterator<T> _iteratorT;
  final Iterator<U> _iteratorU;
  (T, U)? _current;

  _IteratorZip2(Iterator<T> iteratorsT, Iterator<U> iteratorU)
      : _iteratorT = iteratorsT,
        _iteratorU = iteratorU;

  @override
  bool moveNext() {
    if (!_iteratorT.moveNext()) {
      _current = null;
      return false;
    }
    if (!_iteratorU.moveNext()) {
      _current = null;
      return false;
    }
    _current = (_iteratorT.current, _iteratorU.current);
    return true;
  }

  @override
  (T, U) get current => _current ?? (throw StateError('No element'));
}

Examples of zip functions in other languages