How to convert a `List` to `Set` using literals - flutter

final _set = [1, 1, 2, 3, 4].toSet();
besides effective dart suggesting prefer_collection_literals
it really looks like java or c# rather than dart (no offense)
does anybody knows
How to convert a List to Set using literals
(suggesting to add // ignore: prefer_collection_literals isn't an answer)

You can do something like this:
main() {
final list = [1, 1, 2, 3, 4];
final _set = {...list};
print('set: $_set'); // set: {1, 2, 3, 4}
}

You can write the same code as final _set = {1, 1, 2, 3, 4};.
When you write {key: value, key: value} that is a Map literal, but if you just do {value, value, ...} that becomes a Set literal.

Related

Dart - For loop is changing elements of my list even when it is cloned

When I access to the elements of my list in a for loop, I would like to be able to modify them without impacting the original list.
Here's a simple example :
List pairs = [
[1,8],
[1,6],
];
print(pairs);
List copy = List.from(pairs);
for (List pair in copy) {
if(pair.contains(1)) {
pair.remove(1);
}
}
print(pairs);
The output of this is :
[[1, 8], [1, 6]]
[[8], [6]]
I expected the output to be :
[[1, 8], [1, 6]]
[[1, 8], [1, 6]]
I tried to replace List copy = List.from(pairs); with :
List copy = [...pairs]; // This
List copy = []..addAll(pairs); // Or this
Nothing is working.
The only solution I found was to do this :
List temp = List.from(pair);
if(temp.contains(1)) {
temp.remove(1);
}
But it seems to be a bit overkill. Does anyone has another idea ?
As jamesdlin says, using List.from or the spread operator just creates a shallow copy of the list. Dart does not have a built-in deep copy function that I could find, but if you'll only be working with nested lists like this we can define our own pretty easily:
List<T> deepCopy<T>(List<T> list) =>
list.map((e) => e is List ? deepCopy(e) : e).cast<T>().toList();
Here's a dartpad showing the result.

list.removeWhere, to remove only 1 occurence of condition

suppose i have a list:
List? myList = [{Person: 1},{Person: 1},{Person: 2},{Person: 3},{Person: 4},{Person: 5}];
I would like to remove the first occurrence of '1' using list.removeWhere.
How can I achieve this? I tried this one below but it removed all '1's.
myList.removeWhere((e) => e['Person'] == 1);
You can get the first item then remove it from list. removeWhere removes all elements that satisfy its condition
void main(List<String> args) {
List? myList = [
{"Person": 1},
{"Person": 1},
{"Person": 2},
{"Person": 3},
{"Person": 4},
{"Person": 5}
];
final item = myList.firstWhere((e) => e['Person'] == 1);
myList.remove(item);
print(myList);
}
Or
final int item = myList.indexWhere((e) => e['Person'] == 1);
myList.removeAt(item);

How to add a new value to Map in Dart?

this is my first post to StackOverflow.
I have been struggling with the Map data.
It’s been taking too much time to find a way more than I thought...
Ex)
Map<String, int> someMap = {
"a": 1,
"b": 2,
"c": 3,
};
How can I add a new value to the same key Map?
like this.
a:1, b:2, c:3,4,5,6etc....
I'd be grateful if you could tell me the correct way.
Thank you.
If you want multiple values for the same key, you'll need to change the value type: Right now it's int, but that can only be a single int, and by definition, a key only occurs once in a map.
If you change the type of the value to List<int>, you can add multiple values for the same key:
Map<String, List<int>> someMap = {
"a": [1],
"b": [2,3],
"c": [4],
};
Now, to add more values, you could simply access the list and add values to it:
someMap["c"].add(5); // c: [4, 5]
someMap["c"].addAll([6,7,8]); // c: [4, 5, 6, 7, 8]

Sort a map within a map and convert to list within a list

Here's my data in Firebase:
prices
price1
priceAmount1: 10
priceAmount2: 20
priceAmount3: 30
price2
priceAmount1: 15
priceAmount2: 5
priceAmount3: 7
price3
priceAmount1: 2
priceAmount2: 4
priceAmount3: 6
If I straight away retrieve it. Sometimes the ordering is price2, price3, price1. So I tried sorting it like this:
var sortedKeys = prices!.price!.keys.toList()..sort();
for (var it = 0; it < sortedKeys.length; it++) {
print('${sortedKeys[it]}');
}
But since it becomes a list, I'm not able to access the map anymore. I wanted to sort the map within a map then store it in a list within a list. Please help. Thanks!
Edit:
final splayByPrice =
SplayTreeMap<dynamic, dynamic>((a, b) => a.compareTo(b));
List<Map<dynamic, dynamic>> priceAmountMap = [
{
'priceAmount1': 10,
'priceAmount2': 20,
'priceAmount3': 30,
},
{
'priceAmount1': 15,
'priceAmount2': 5,
'priceAmount3': 7,
},
{
'priceAmount1': 2,
'priceAmount2': 4,
'priceAmount3': 6,
}
];
Map<dynamic, Map<dynamic, dynamic>> priceMap = {
'price2': priceAmountMap[1],
'price1': priceAmountMap[0],
'price3': priceAmountMap[2],
};
priceMap.forEach((key, value) {
splayByPrice.addAll(value);
});
priceMap.forEach((key, value) {
print('$key \t $value');
});
What it prints, is still not sorted.
price2 {priceAmount1: 15, priceAmount2: 5, priceAmount3: 7}
price1 {priceAmount1: 10, priceAmount2: 20, priceAmount3: 30}
price3 {priceAmount1: 2, priceAmount2: 4, priceAmount3: 6}
Dart's default Map implementation is a LinkedHashMap that stores entries in order of insertion.
(You haven't provided code that clearly shows your data structure, so I'll use my own example.)
If you want the Map to be sorted by the keys' alphabetic order, then you could:
Create a new Map, adding items to it in the desired order:
var theMap = {
4: 'four',
7: 'seven',
6: 'six',
9: 'nine',
5: 'five',
1: 'one',
8: 'eight',
0: 'zero',
3: 'three',
2: 'two',
};
void main() {
var sortedKeys = theMap.keys.toList()..sort();
var sortedMap = {
for (var key in sortedKeys)
key: theMap[key]!,
};
print(sortedMap);
}
Update the existing Map, removing and re-adding items in the desired order:
void main() {
var sortedKeys = theMap.keys.toList()..sort();
for (var key in sortedKeys) {
var value = theMap[key]!;
theMap.remove(key);
theMap[key] = value;
}
print(theMap);
}
Use a SplayTreeMap, which keeps entries sorted by a comparison rule.
import 'dart:collection';
void main() {
var splayTreeMap = SplayTreeMap.of(theMap);
print(splayTreeMap);
}
If you need to sort the data only once, I'd use one of the first two methods. If you're frequently adding new entries, then I'd use a SplayTreeMap instead of a Map/LinkedHashMap so that entries are kept in a sorted order. (But note that lookups, insertions, and removals in a SplayTreeMap are O(log n) instead of O(1).)
Also, if you're sorting strings that contain numbers, you probably don't want to use the normal string sort.

How to get the length for each list according to its key inside map

how to get the length for each list according to its key
Map mymap= <String, List>;
Example
key1 : 5(length of the value(list))
key2 : 48
It seems similar to this,
you can do mymap['k1']?.length, here ?. means it will return null if there is no value.
Rest you can follow #zabaykal's answer.
Map<String, List> mymap = {
"k1": [1, 2, 4],
"k2": [5, 6, 7],
"k3": []
};
print(mymap['k1']?.length);
mymap.forEach((key, value) {
print('$key: ${value.length}');
});
If you want to create a second map with the original keys and the respective lengths as the value you can use the following code where initialMap is the original map with List<T> as values:
final mapListCount = initialMap.map((key, value) => MapEntry(key, value?.length));