読者です 読者をやめる 読者になる 読者になる

とくにあぶなくないRiSKのブログ

危ないRiSKのブログだったかもしれない。本当はRiSKだけどググラビリティとか取得できるIDの都合でsscriskも使ったり。

LINQ for Dart (LINQ4Dart) を使って FizzBuzz

作りかけですが LINQ っぽい Dart 用のライブラリを書きました。
ユーザーコードはこんな感じ。

main() {
 final fizzBuzz =
  range(1, 100)
  .where((i) => i <= 30)
  .select((i) => i % 15 == 0 ? 'FizzBuzz'
               : i % 5  == 0 ? 'Buzz'
               : i % 3  == 0 ? 'Fizz'
               : '$i');
 for(final s in fizzBuzz)
  print(s);
}

実行結果:

1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz

コード全体
LINQ for Dart

interface Enumerable<Source> extends Iterable
{
 Enumerable<Source> where(bool filter(Source));
 Enumerable select(/*Dynamic selector(Source)*/var selector);
}

class Enumerator<Source> implements Enumerable<Source>
{
 Enumerable<Source> where(bool filter(Source)) => new Where<Source>(this, filter);
 Enumerable select(/*Result selector(Source)*/var selector) => new Select<Source>(this, selector);
}

class RangeIterator implements Iterator<int>
{
 final int _num;
 final int _count;
 int _i;

 RangeIterator(this._num, this._count)
  : _i = 0;
 bool hasNext() => _i < _count;
 int next() {
  if(hasNext())
   return _num + _i++;
  else
   throw new NoMoreElementsException();
 }
}

class Range extends Enumerator<int>
{
 final int _num;
 final int _count;

 Range(this._num, this._count);
 Iterator<int> iterator() => new RangeIterator(_num, _count);
}

Range range(int start, int count) => new Range(start, count);

class Query<Source> extends Enumerator<Source>
{
 final Iterable<Source> _iterable;

 Query(this._iterable);
 Iterator<Source> iterator() => _iterable.iterator();
}

class WhereIterator<Source> implements Iterator<Source>
{
 final Iterator<Source> _iterator;
 final _filter;
 Source _current;

 WhereIterator(this._iterator, this._filter);
 bool hasNext() {
  if(_current != null)return true;
  for(; _iterator.hasNext();) {
   final Source tmp = _iterator.next();
   if(_filter(tmp)) {
    _current = tmp;
     return true;
   }
  }
  return false;
 }

 Source next() {
  if(_current == null && !hasNext())
   throw new NoMoreElementsException();
  final Source tmp = _current;
  _current = null;
  return tmp;
 }
}

class Where<Source> extends Query<Source>
{
 final _filter;

 Where(Iterable<Source> iterable, this._filter)
  : super(iterable);
 Iterator<Source> iterator() => new WhereIterator<Source>(_iterable.iterator(), _filter);
}

class SelectIterator<Source> implements Iterator
{
 final Iterator<Source> _iterator;
 final _selector;

 SelectIterator(this._iterator, this._selector);
 bool hasNext() => _iterator.hasNext();
 next() => _selector(_iterator.next());
}

class Select<Source> extends Query<Source>
{
 final _selector;

 Select(Iterable<Source> iterable, this._selector)
  : super(iterable);
 Iterator iterator() => new SelectIterator<Source>(_iterable.iterator(), _selector);
}

class From<Source> extends Query<Source>
{
 From(Iterable<Source> iterable)
  : super(iterable);
}

main() {
 final fizzBuzz =
  range(1, 100)
  .where((i) => i <= 30)
  .select((i) => i % 15 == 0 ? 'FizzBuzz'
               : i % 5  == 0 ? 'Buzz'
               : i % 3  == 0 ? 'Fizz'
               : '$i');
 for(final s in fizzBuzz)
  print(s);
}