Get iteration index from List.map()
LoopsDictionaryIndexingDartFlutterLoops Problem Overview
I wrote an iteration on list of letters and put inside cards on screen using "map" class.
In the code you can see that I made a row, and using "map" printed all the userBoard on cards to the screen. I want to add some logic inside so I need to get the id of the element (for taping event). Is there a way that I can do that?
Actually, I want to get a specific index of element over userBoard.
Code:
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Row(
children: userBoard
.map((element) => Stack(children: <Widget>[
Align(
alignment: Alignment(0, -0.6),
child: GestureDetector(
onTap: (() {
setState(() {
// print("element=${element.toString()}");
// print("element=${userBoard[element]}");
});
}),
child: SizedBox(
width: 40,
height: 60,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0),
),
child: Center(
child: Text(element,
style: TextStyle(fontSize: 30)),
)),
),
),
)
]))
.toList(),
)
],
),
}
Picture - each card is "element" of the map. I want to get the indexes for the function onTap.
Loops Solutions
Solution 1 - Loops
To get access to index, you need to convert your list to a map using the asMap operator.
Example
final fruitList = ['apple', 'orange', 'mango'];
final fruitMap = fruitList.asMap(); // {0: 'apple', 1: 'orange', 2: 'mango'}
// To access 'orange' use the index 1.
final myFruit = fruitMap[1] // 'orange'
// To convert back to list
final fruitListAgain = fruitMap.values.toList();
Your Code
userBoard.asMap().map((i, element) => MapEntry(i, Stack(
GestureDetector(onTap: () {
setState(() {
// print("element=${element.toString()}");
// print("element=${userBoard[i].toString()}");
});
}),
))).values.toList();
Solution 2 - Loops
You can get index use list.indexOf
when the list has no duplicate elements。
Example
userBoard.map((element) {
// get index
var index = userBoard.indexOf(element);
return Container(
);
}).toList()
Solution 3 - Loops
The easiest approach if you want to iterate
We can extend Iterable
with a new function:
import 'dart:core';
extension IndexedIterable<E> on Iterable<E> {
Iterable<T> mapIndexed<T>(T Function(E e, int i) f) {
var i = 0;
return map((e) => f(e, i++));
}
}
Usage:
myList.mapIndexed((element, index) {});
Taken from here.
Solution 4 - Loops
Dart has released the collection
package that comes with a mapIndexed
extension to all Iterables.
import 'package:collection/collection.dart';
void main() {
final fruitList = ['apple', 'orange', 'mango'];
final withIndices = fruitList.mapIndexed((index, fruit) => "$index - $fruit");
print(withIndices);
}
(DartPad)
The package comes with all sorts of handy extensions and useful tools to work with collections.
Solution 5 - Loops
Another approach using List.generate
:
var list = ['y', 'e', 's'];
var widgets = List.generate(list.length, (i) => Text(list[i]));
Solution 6 - Loops
You can simply use the mapIndexed
method:
userBoard.mapIndexed(
(int index, element) => Container( ... ))
.toList();
This is one of the many extensions from the FIC package: https://pub.dev/packages/fast_immutable_collections
If you don't want to add a package to your project you can just copy the extension itself:
extension FicListExtension<T> on List<T> {
/// Maps each element of the list.
/// The [map] function gets both the original [item] and its [index].
Iterable<E> mapIndexed<E>(E Function(int index, T item) map) sync* {
for (var index = 0; index < length; index++) {
yield map(index, this[index]);
}
}
}
Note: I'm one of the authors of that package.
Update: I have now removed a few methods, like Iterable.mapIndexed()
from the FIC package, because Google added a similar method to their collection package, and I want both packages to be compatible.
Solution 7 - Loops
You can try this
children: [
for(int index = 0; index < list.length; index++)
Text(list[index])
]
Solution 8 - Loops
You can use asMap() and entries.map() to get the index.
list.asMap().entries.map((e) {
var index = e.key;
var value = e.value;
// ...
}
Solution 9 - Loops
You can use list.asMap()
var result = list.asMap().map((e) => '${e[0]} - ${e[1]});
print(result);
https://api.dartlang.org/stable/2.2.0/dart-core/List/asMap.html
Solution 10 - Loops
There is no build-in function to get the iteration index.
What you probably want is a map
which gives you the index:
children: enumerate(
list,
(index, item) => Text("event_$index")
).toList();
The implementation of enumerate
is simple:
Iterable<E> enumerate<E, T>(
Iterable<T> items, E Function(int index, T item) f) {
var index = 0;
return items.map((item) {
final result = f(index, item);
index = index + 1;
return result;
});
}
Solution 11 - Loops
Another Solution is get hascode of your object is a unique as int example:
yourClass.hasCode()
this will return a id like 123456789 for each iteration
you when use in another widgets when you need
onSelectChanged: (d) {
setState(() {
selectedRow = d == true ? object.hascode : null;
});
},
selected: object.hascode == selectedRow,
Solution 12 - Loops
Can also try this:
list.asMap().keys.toList().map((index) {
// var item = list[index];
// index is the index of each element.
return youFunction(index);
});
I also write other approaches as well in my blog here. https://medium.com/@channaly/map-with-index-in-dart-flutter-6e6665850ea8
Solution 13 - Loops
You can use package:quiver
's enumerate
function first:
enumerate(userBoard).map((indexedValue) {
final index = indexedValue.index;
final element = indexedValue.value;
// ...
})
Solution 14 - Loops
Transform your list to another using map
.
var yourList = ['A', 'B', 'C'];
var textList = yourList.map((e) => Text(e)).toList();
Usage:
Column(
children: textList,
)
Solution 15 - Loops
its pretty simple and straight forward in dart.
myList.map((item) =>
print(myList.indexOf(item));//here I printing index
).toList()
Solution 16 - Loops
The current version of built-in collection package now contains the method mapIndexed
and comprehensive set of other List
/Iterable
extension methods.
import 'package:collection/collection.dart';
Solution 17 - Loops
Map map = {
'1st':'first',
'2nd':'second'}; //any data
List mapAsList = map.keys.toList(); //convert map to list to get iteration index
print( map[mapAsList[0]] ); //first
print( map[mapAsList[1]] ); //second
Solution 18 - Loops
source
Try this:(Key in map) same (index in list)
myList.asMap().entries.map((entry) {
int idx = entry.key;
String val = entry.value;
return something;
}