If you're using Dart and you need to convert a List
into a Map
, you can find the examples here.
In this tutorial, we are going to convert List
of Item
instances to Map
. Here is the Item
class.
class Item {
int id;
String name;
int quantity;
Item({this.id, this.name, this.quantity});
}
And here is the List
to be converted.
Item item1 = new Item(id: 1, name: 'Item one', quantity: 1);
Item item2 = new Item(id: 2, name: 'Item two', quantity: 2);
Item item3 = new Item(id: 3, name: 'Item three', quantity: 3);
Item item4 = new Item(id: 1, name: 'Item four', quantity: 4);
List<Item> items = [item1, item2, item3, item4];
There are several ways to convert the List
into a Map
.
Using fromIterable
Dart's Map
has a static method fromIterable
, which creates a Map
instance from an Iterable
. To set what should be the key and the value, you need to pass key
and value
options. If you don't pass key
or value
, identity function will be used. If there are multiple elements with the same key, the last occurrence will be used.
Map<int, String> result = Map.fromIterable(items, key: (v) => v.id, value: (v) => v.name);
print(result);
Output:
{1: Item four, 2: Item two, 3: Item three}
Using Collection-for
Since Dart 2.3, it's possible to build a collection using collection-for. With a very short code below, we can create a Map
whose key is the id
while the name
becomes the value. Like using fromIterable
, the latest occurrence replaces the previous one.
Map<int, String> result = { for (var v in items) v.id: v.name };
print(result);
Output:
{1: Item four, 2: Item two, 3: Item three}
Iterating Through the List
If you need to use custom logic, iterating each element is a suitable way as it gives you freedom to set the keys and values.
Using the previous two examples, if there is duplicate key, the last occurrence will be used. If you want to use the first occurrence instead, you can do it by iterating through the list and using putIfAbsent
method to determine whether a new entry should be added or not.
Map<int, Item> result = {};
for (Item item in items) {
result.putIfAbsent(item.id, () => item);
}
result.forEach((id, item) {
print('$id: ${item.name} - ${item.quantity}');
});
Output:
1: Item one - 1
2: Item two - 2
3: Item three - 3
Another example, this time it sums the quantity
value if the key is already exist.
Map<int, Item> result = {};
for (Item item in items) {
int key = item.id;
if (!result.containsKey(key)) {
result[key] = item;
} else {
Item existingValue = result[key];
existingValue.quantity += item.quantity;
}
}
result.forEach((id, item) {
print('$id: ${item.name} - ${item.quantity}');
});
Output:
1: Item one - 5
2: Item two - 2
3: Item three - 3