Comment puis-je créer facilement une plage d'entiers consécutifs dans dart? Par exemple:
// throws a syntax error :)
var list = [1..10];
Vous pouvez utiliser le constructeur List.generate :
var list = new List<int>.generate(10, (i) => i + 1);
Vous pouvez alternativement utiliser un générateur:
/// 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]
}
avec Dart 2.3. :
var list = [for(var i=0; i<10; i+=1) i];
Vous pouvez également utiliser la fonction Iterable.generate de Dart pour créer une plage entre 0..n-1
var list = Iterable<int>.generate(10).toList()
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Pour autant que je sache, il n'y a pas de méthode équivalente native pour le faire dans Dart. Cependant, vous pouvez créer votre propre classe Range
, ou utiliser https://pub.dartlang.org/packages/range si cela ne vous dérange pas.
Olov Lassus a écrit n article sur l'implémentation de votre propre classe Range il y a quelque temps
edit: une façon encore meilleure que je viens de penser:
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);
}
}
J'ai utilisé une version modifiée d'Alexandre Ardhuin qui essaie d'imiter la plage () fournie par python Edit: découvert que les arguments positionnels optionnels sont une chose mise à jour le code ci-dessous
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))
: [];
}
Exemple d'utilisation:
range(16, start:-5, step: 8);
// [-5, 3, 11]
range(5);
// [0, 1, 2, 3, 4]
Malheureusement, je n'ai pas complètement imité la syntaxe la plus simple de python (range (start, stop [ step])) car Dart n'a pas de surcharge d'opérateur ou d'arguments positionnels optionnels.
Une autre option utilisant la compréhension de liste qui ressemble à la solution de 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)]
: [];
}
Exemple d'utilisation:
listCompRange(0, 5, 1);
// [0, 1, 2, 3, 4]
J'ai comparé ces deux options avec les méthodes suivantes
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;
}
ce qui a donné ces résultats favorisant légèrement le générateur.
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
cependant, lorsque j'ai changé la fonction pour générer de -10 à -30 avec un pas de -2, les résultats ont légèrement favorisé la compréhension de la liste.
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
Code mis à jour avec des paramètres positionnels plutôt que nommés
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))
: [];
}
Utilisation: plage (int a, [int stop, int step])
Si stop n'est pas inclus, un devient stop et start sera réglé par défaut sur 0 Si a et stop sont tous deux fournis, un devient start si non fourni, l'étape par défaut sera 1 ou -1 selon que start ou stop est plus grand
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
Il existe de nombreux itérateurs de type Python définis dans le package Quiver .
Par exemple, utilisez la fonction range()
:
import 'package:quiver/iterables.Dart';
print(range(10).toList().toString());
Production:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Cela fonctionne également très bien dans for
loops:
for (var i in range(1, 11))
print('$i');
Beaucoup d'autres itérateurs utiles sont également fournis.