web-dev-qa-db-ja.com

Dart:0からNまでのリストを作成します

Dartで連続した整数の範囲を簡単に作成するにはどうすればよいですか?例えば:

// throws a syntax error :)
var list = [1..10];
43
Cequiel

List.generateコンストラクタ を使用できます。

var list = new List<int>.generate(10, (i) => i + 1);

代わりにジェネレータを使用することができます:

/// the list of positive integers starting from 0
Iterable<int> get positiveIntegers sync* {
  int i = 0;
  while (true) yield i++;
}
void main() {
  var list = positiveIntegers
      .skip(1)   // don't use 0
      .take(10)  // take 10 numbers
      .toList(); // create a list
  print(list);   // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
}
70

Dart 2.3. を使用:

var list = [for(var i=0; i<10; i+=1) i];
23
Maryan

DartのIterable.generate関数を使用して、0〜n-1の範囲を作成することもできます。

var list = Iterable<int>.generate(10).toList()
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
21
David Rees

私の知る限り、ダートでこれを行うネイティブの同等の方法はありません。ただし、独自のRangeクラスを作成するか、依存関係を気にしない場合は https://pub.dartlang.org/packages/range を使用できます。

Olov Lassusが書いた 記事 しばらく前に独自のRangeクラスの実装について

編集:私が考えたさらに良い方法:

Iterable<int> range(int low, int high) sync* {
  for (int i = low; i < high; ++i) {
    yield i;
  }
}

void main() {
  for(final i in range(1, 20)) {
    print(i);
  }
}
7
Pacane

python 編集:オプションの位置引数は以下の更新されたコードであることが判明した=

range(int stop, {int start: 0, int step: 1}){
  if (step == 0)
    throw Exception("Step cannot be 0");

  return start < stop == step > 0
  ? List<int>.generate(((start-stop)/step).abs().ceil(), (int i) => start + (i * step))
  : [];
}

使用例:

range(16, start:-5, step: 8);
// [-5, 3, 11]
range(5);
// [0, 1, 2, 3, 4]

残念ながら、Dartには演算子のオーバーロードやオプションの位置引数がないため、python(range(start、stop [、step]))の簡単な構文を完全に模倣していません。

Maryanの解に似たリスト内包表記を使用する別のオプション

listCompRange(int start, int stop, int step) {
  if (step == 0)
    throw Exception("Step cannot be 0");
  if (start == stop)
    return [];
  bool forwards = start < stop;
  return forwards == step > 0
  ? forwards 
    ? [for (int i = 0; i*step < stop-start; i++) start + (i * step)]
    : [for (int i = 0; i*step > stop-start; i++) start + (i * step)]
  : [];
}

使用例:

listCompRange(0, 5, 1);
// [0, 1, 2, 3, 4]

これらのオプションの両方を次の方法でベンチマークしました

benchMarkRange(){
  List<List<int>> temp = List<List<int>>();
  Stopwatch timer = Stopwatch();
  timer.start();
  for (int i = 0; i < 500; i++){
    temp.add(range(-30, start: -10, step: -2));
  }
  timer.stop();
  print("Range function\n${timer.elapsed}\n");
  return temp;
}

benchMarkListComprehension(){
  List<List<int>> temp = List<List<int>>();
  Stopwatch timer = Stopwatch();
  timer.start();
  for (int i = 0; i < 500; i++){
    temp.add(listCompRange(-10, -30, -2));
  }
  timer.stop();
  print("List comprehension\n${timer.elapsed}\n");
  return temp;
}

これにより、ジェネレーターにわずかに有利なこれらの結果が得られました。

Range function
0:00:00.011953
0:00:00.011558
0:00:00.011473
0:00:00.011615

List comprehension
0:00:00.016281
0:00:00.017403
0:00:00.017496
0:00:00.016878

ただし、関数を変更して-10から-30に生成し、ステップを-2にすると、結果はリストの理解にわずかに有利になりました。

List comprehension
0:00:00.001352             
0:00:00.001328                
0:00:00.001300
0:00:00.001335

Range function
0:00:00.001371
0:00:00.001466
0:00:00.001438
0:00:00.001372

名前付きパラメーターではなく位置パラメーターを使用してコードを更新

range(int a, [int stop, int step]) {
  int start;

  if (stop == null) {
    start = 0;
    stop = a;
  } else {
    start = a;
  }  

  if (step == 0)
    throw Exception("Step cannot be 0");

  if (step == null)
    start < stop 
    ? step = 1    // walk forwards
    : step = -1;  // walk backwards

  // return [] if step is in wrong direction
  return start < stop == step > 0
  ? List<int>.generate(((start-stop)/step).abs().ceil(), (int i) => start + (i * step))
  : [];
}

使用法:range(int a、[int stop、int step])

Stopが含まれていない場合、aはstopとstartがデフォルトで0になります。aとstopの両方が指定されている場合、aはstartが指定されていない場合、デフォルトで1または-1になります。

range(4);
// [0, 1, 2, 3]
range(4, 10);
// [4, 5, 6, 7, 8, 9]
range(4, 10, 2);
// [4, 6, 8]
range(-4);
// [0, -1, -2, -3]
range(10, 4);
// [10, 9, 8, 7, 6, 5]
range(10,10);
// []
range(1, 2, -1);
// []
range(x, y, 0);
// Exception
3
alexanderhurst

Quiver パッケージでは、Pythonに似たイテレータが多数定義されています。

たとえば、range()関数を使用します。

import 'package:quiver/iterables.Dart';

print(range(10).toList().toString());

出力:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

forloopsでも正常に機能します。

for (var i in range(1, 11))
  print('$i');

他の多くの 便利なイテレータ も提供されます。

0
Ber