En fléchette il y a tout équivalent au commun:
enumerate(List) -> Iterator((index, value) => f)
or
List.enumerate() -> Iterator((index, value) => f)
or
List.map() -> Iterator((index, value) => f)
Il semble que ce soit le moyen le plus simple, mais il semble toujours étrange que cette fonctionnalité n'existerait pas.
Iterable<int>.generate(list.length).forEach( (index) => {
newList.add(list[index], index)
});
Éditer:
Grâce à @ hemanth-raj, j'ai pu trouver la solution que je recherchais. Je vais mettre ceci ici pour tous ceux qui ont besoin de faire quelque chose de similaire.
List<Widget> _buildWidgets(List<Object> list) {
return list
.asMap()
.map((index, value) =>
MapEntry(index, _buildWidget(index, value)))
.values
.toList();
}
Vous pouvez également créer une fonction de générateur synchrone pour renvoyer un itérable
Iterable<MapEntry<int, T>> enumerate<T>(Iterable<T> items) sync* {
int index = 0;
for (T item in items) {
yield MapEntry(index, item);
index = index + 1;
}
}
//and use it like this.
var list = enumerate([0,1,3]).map((entry) => Text("index: ${entry.key}, value: ${entry.value}"));
Map#forEach
? c'est ce que tu veux?List
? Que voulez-vous dire? les documents disent: "Applique f à chaque paire clé / valeur de la carte. L'appel de f ne doit pas ajouter ou supprimer des clés de la carte."Réponses:
Il existe une
asMap
méthode qui convertit la liste en une carte où les clés sont l'index et les valeurs sont l'élément à l'index. Veuillez consulter la documentation ici .Exemple:
List _sample = ['a','b','c']; _sample.asMap().forEach((index, value) => f);
J'espère que cela t'aides!
la source
Il n'y a pas de fonction intégrée pour obtenir l'index d'itération.
Si comme moi vous n'aimez pas l'idée de construire une
Map
(la structure de données) juste pour un simple index, ce que vous voulez probablement est unemap
(la fonction) qui vous donne l'index. Appelons-lemapIndexed
(comme dans Kotlin):children: mapIndexed( list, (index, item) => Text("event_$index") ).toList();
La mise en œuvre de
mapIndexed
est simple:Iterable<E> mapIndexed<E, T>( Iterable<T> items, E Function(int index, T item) f) sync* { var index = 0; for (final item in items) { yield f(index, item); index = index + 1; } }
la source
mapIndexed
.asMap().forEach()
c'est essentiellement la même chose - voir ma réponse.asMap()
cela coûtera une boucle supplémentaire pour récupérer les données, donc cela ne sera pas efficace commemapIndexed()
ci-dessus.S'appuyant sur la réponse @Hemanth Raj.
Pour le reconvertir, vous pouvez le faire
List<String> _sample = ['a', 'b', 'c']; _sample.asMap().values.toList(); //returns ['a', 'b', 'c'];
Ou si vous avez besoin de l'index pour une fonction de mappage, vous pouvez le faire:
_sample .asMap() .map((index, str) => MapEntry(index, str + index.toString())) .values .toList(); // returns ['a0', 'b1', 'c2']
la source
À partir de Dart 2.7, vous pouvez utiliser
extension
pour étendre les fonctionnalités deIterable
au lieu d'avoir à écrire des méthodes d'assistanceextension ExtendedIterable<E> on Iterable<E> { /// Like Iterable<T>.map but callback have index as second argument Iterable<T> mapIndex<T>(T f(E e, int i)) { var i = 0; return this.map((e) => f(e, i++)); } void forEachIndex(void f(E e, int i)) { var i = 0; this.forEach((e) => f(e, i++)); } }
Usage:
final inputs = ['a', 'b', 'c', 'd', 'e', 'f']; final results = inputs .mapIndex((e, i) => 'item: $e, index: $i') .toList() .join('\n'); print(results); // item: a, index: 0 // item: b, index: 1 // item: c, index: 2 // item: d, index: 3 // item: e, index: 4 // item: f, index: 5
inputs.forEachIndex((e, i) => print('item: $e, index: $i')); // item: a, index: 0 // item: b, index: 1 // item: c, index: 2 // item: d, index: 3 // item: e, index: 4 // item: f, index: 5
la source
Le package plus de Lukas Renggli comprend de nombreux outils utiles, y compris «indexé» qui fait exactement ce que vous voulez. À partir de la documentation:
indexed(['a', 'b'], offset: 1) .map((each) => '${each.index}: ${each.value}') .join(', ');
(Vous pouvez ignorer l'argument offset sauf si vous avez un arrière-plan Smalltalk :-).
la source
J'ai d'abord pensé que ce
['one', 'two', 'three'].asMap().forEach((index, value) { ... });
serait vraiment inefficace car il semble que cela convertisse la liste en carte. En fait, ce n'est pas le cas - la documentation dit que cela crée une vue immuable de la liste. J'ai vérifié avec ledart2js
de ce code:void main() { final foo = ['one', 'two', 'three']; foo.asMap().forEach((idx, val) { print('$idx: $val'); }); }
Cela génère beaucoup de code! Mais l'essentiel est ceci:
main: function() { var foo = H.setRuntimeTypeInfo(["one", "two", "three"], ...); new H.ListMapView(foo, ...).forEach$1(0, new F.main_closure()); }, H.ListMapView.prototype = { forEach$1: function(_, f) { var t1, $length, t2, i; ... t1 = this._values; $length = t1.length; for (t2 = $length, i = 0; i < $length; ++i) { if (i >= t2) return H.ioore(t1, i); f.call$2(i, t1[i]); t2 = t1.length; if ($length !== t2) throw H.wrapException(P.ConcurrentModificationError$(t1)); } }, ... }, F.main_closure.prototype = { call$2: function(idx, val) { ... H.printString("" + idx + ": " + H.S(val)); }, $signature: 1 };
Il est donc assez intelligent pour faire la chose efficace! Assez intelligent.
Bien sûr, vous pouvez également utiliser une boucle for normale:
for (var index = 0; index < values.length; ++index) { final value = values[index];
la source
Pour plus de commodité, vous pouvez utiliser cette méthode d'extension.
extension CollectionUtil<T> on Iterable<T> { Iterable<E> mapIndexed<E, T>(E Function(int index, T item) transform) sync* { var index = 0; for (final item in this) { yield transform(index, item as T); index++; } } }
la source
Utilisez asMap pour convertir la liste en carte en premier. L'index d'élément est la clé. L'élément devient valeur. Utilisez des entrées pour mapper la clé et la valeur à tout ce que vous voulez.
List rawList = ["a", "b", "c"]; List<String> argList = rawList.asMap().entries.map((e) => '${e.key}:${e.value}').toList(); print(argList);
Production:
[0:a, 1:b, 2:c]
la source