Suppose I have these maps:
Map<int,List<String>> firstMap = {1:["a", "b"]};
Map<int,List<String>> secondMap = {2:["c"]};
Map<int,List<String>> thirdMap = {1:["d"]};
I want to merge them without overwriting values with same key to have this output:
{1: [a, b, d], 2: [c]
I used both spread operator and adAll method and both overwrite the value for key 1 to have {1: [d], 2: [c]}
instead of {1: [a, b, d], 2: [c].
void main() {
Map<int, List<String>> firstMap = {1: ["a", "b"]};
Map<int, List<String>> secondMap = {2: ["c"]};
Map<int, List<String>> thirdMap = {1: ["d"]};
var mergedMap = <int, List<String>>{};
for (var map in [firstMap, secondMap, thirdMap]) {
for (var entry in map.entries) {
// Add an empty `List` to `mergedMap` if the key doesn't already exist
// and then merge the `List`s.
(mergedMap[entry.key] ??= []).addAll(entry.value);
}
}
print(mergedMap); // Prints: {1: [a, b, d], 2: [c]}
}
Related
i want to split a word into characters. "Amir Abbas" it contains one space. i use:
List<String> singleWord = string.trim().split("");
but final result is:
A, m, i, r, " ", "", A, b, b, a, s
what is "" character? how to exclude it?
I use it in flutter and ios emulator.
The following code does not give your result. It is not splitting an empty character for me. Try typing your string again, eventually you might have a hidden illegal character?
void main() {
List<String> singleWord = "Amir Abbas".trim().split("");
singleWord.forEach((element){
print(element);
});
}
You can filter the list with the where method and exclude the empty spaces
void main() {
List<String> a = ["a", "b", ""];
List<String> b = a.where((e) => e != "").toList();
print(a); // ["a", "b", ""]
print(b); // ["a", "b"]
}
It is working perfectly for me in dart pad and in my application.Run the application again and can u submit the output again
Try this approach by replacing trim() and just using split(). You can alter the below code according to your need
var names = "Amir and Abbas";
List<String> namesSplit = names.split(" ");
for(var i=0;i<namesSplit.length;i++){
for(var j=0; j<namesSplit[i].length;j++){
print(namesSplit[i][j]);
}
}
Output:
A
m
i
r
a
n
d
A
b
b
a
s
You can filter the runes and get all the letters from A-z.
List<String> singleWord = runes.where((rune) => rune > 64 && rune < 123).map((rune) => String.fromCharCode(rune)).toList()
print(singleWord); // prints [A, m, i, r, A, b, b, a, s]
I have a list that's formatted like {0:"a", 1:"b", 2:"c", 3: "a"} and want to remove dublicate values so that I end up with {0:"a", 1:"b", 2:"c"}. I'm also fine with geting {1:"b", 2:"c", 3: "a"}. What's the most idiomatic way to do this filtering?
package:quiver provides a bidirectional map (BiMap) that makes it an error to add elements that don't have unique values.
Alternatively, one easy way to filter duplicate values is to create a separate Set of values and use it to rebuild the Map:
Map<K, V> removeDuplicateValues<K, V>(Map<K, V> map) {
var valuesSoFar = <V>{};
return {
for (var mapEntry in map.entries)
if (valuesSoFar.add(mapEntry.value)) mapEntry.key: mapEntry.value,
};
}
void main() {
var map = {0: "a", 1: "b", 2: "c", 3: "a"};
print(removeDuplicateValues(map)); // Prints: {0: a, 1: b, 2: c}
}
If you want to change an existing map, you can do the following. I have made it as a extension method but you can of course also just have it as a separate method or some lines of codes:
extension RemoveDuplicateValuesExtension<K, V> on Map<K, V> {
void removeDuplicateValues() {
final valuesSoFar = <V>{};
this.removeWhere((_, value) => !valuesSoFar.add(value));
}
}
void main() {
final map = {0: "a", 1: "b", 2: "c", 3: "a"}..removeDuplicateValues();
print(map); // Prints: {0: a, 1: b, 2: c}
}
I have a dart list:
List<String?> vals;
I want to remove any null values and convert it to a List<String>.
I've tried:
List<String> removeNulls(List<String?> list) {
return list.where((c) => c != null).toList() as List<String>;
}
At run time I'm getting the following error:
List<String?>' is not a subtype of type 'List<String>?'
What is the correct way to resolve this?
Ideally you'd start with a List<String> in the first place. If you're building your list like:
String? s = maybeNullString();
var list = <String?>[
'foo',
'bar',
someCondition ? 'baz' : null,
s,
];
then you instead can use collection-if to avoid inserting null elements:
String? s = maybeNullString();
var list = <String?>[
'foo',
'bar',
if (someCondition) 'baz',
if (s != null) s,
];
An easy way to filter out null values from an Iterable<T?> and get an Iterable<T> result is to use .whereType<T>(). For example:
var list = <String?>['foo', 'bar', null, 'baz', null];
var withoutNulls = list.whereType<String>().toList();
Another approach is to use collection-for with collection-if:
var list = <String?>['foo', 'bar', null, 'baz', null];
var withoutNulls = <String>[
for (var s in list)
if (s != null) s
];
Finally, if you already know that your List doesn't contain any null elements but just need to cast the elements to a non-nullable type, other options are to use List.from:
var list = <String?>['foo', 'bar', 'baz'];
var withoutNulls = List<String>.from(list);
or if you don't want to create a new List, Iterable.cast:
var list = <String?>['foo', 'bar', 'baz'];
var withoutNulls = list.cast<String>();
Without creating a new List
void main() {
List<String?> list = ['a', null, 'b', 'c', null];
list.removeWhere((e) => e == null); // <-- This is all you need.
print(list); // [a, b, c]
}
Creating a new List
First create a method, filter for example:
List<String> filter(List<String?> input) {
input.removeWhere((e) => e == null);
return List<String>.from(input);
}
You can now use it:
void main() {
List<String?> list = ['a', null, 'b', 'c', null];
List<String> filteredList = filter(list); // New list
print(filteredList); // [a, b, c]
}
To use retainWhere, replace the predicate in removeWhere with (e) => e != null
I am trying to extend a list just by using add method like this
List<String> mylists = ['a', 'b', 'c'];
var d = mylists.add('d');
print(d);
It gives error
This expression has type 'void' and can't be used.
print(d);
Why i cannot save the list in a new variable? Thank you
mylists.add('d') will add the argument to the original list.
If you want to create a new list you have several possibilities:
List<String> mylists = ['a', 'b', 'c'];
// with the constructor
var l1 = List.from(mylists);
l1.add('d');
// with .toList()
var l2 = mylists.toList();
l2.add('d');
// with cascade as one liner
var l3 = List.from(mylists)..add('d');
var l4 = mylists.toList()..add('d');
// in a upcoming version of dart with spread (not yet available)
var l5 = [...myList, 'd'];
Refering Dart docs: https://api.dartlang.org/stable/2.2.0/dart-core/List-class.html
The add method of List class has return type of void.
So you were unable to assign var d.
To save list in new variable use:
List<String> mylists = ['a', 'b', 'c'];
mylists.add('d');
var d = mylists;
print(d);
First add the new String i.e. 'd'
And then assign it to new variable
I have this map:
var temp= {
'A' : 3,
'B' : 1,
'C' : 2
};
How to sort the values of the map (descending). I know, I can use temp.values.toList()..sort().
But I want to sort in context of the keys like this:
var temp= {
'B' : 1,
'C' : 2
'A' : 3,
};
This example uses a custom compare function which makes sort() sort the keys by value. Then the keys and values are inserted into a LinkedHashMap because this kind of map guarantees to preserve the order.
Basically the same as https://stackoverflow.com/a/29629447/217408 but customized to your use case.
import 'dart:collection';
void main() {
var temp= {
'A' : 3,
'B' : 1,
'C' : 2
};
var sortedKeys = temp.keys.toList(growable:false)
..sort((k1, k2) => temp[k1].compareTo(temp[k2]));
LinkedHashMap sortedMap = new LinkedHashMap
.fromIterable(sortedKeys, key: (k) => k, value: (k) => temp[k]);
print(sortedMap);
}
Try it on DartPad
The SplayTreeMap has a named constructor which accepts map and a comparator which is used to sort given map while building new map. Since SplayTreeMap is a descendant of Map you can easily substitute it.
import 'dart:collection';
void main() {
var unsorted = {'A': 3, 'B': 1, 'C': 2};
final sorted = SplayTreeMap.from(
unsorted, (key1, key2) => unsorted[key1].compareTo(unsorted[key2]));
print(sorted);
}
final Map<String, ClassCategory> category;
...
Map<String, ClassCategory> sorted = SplayTreeMap.from(category,
(key1, key2) => category[key1]!.title.compareTo(category[key2]!.title));
for (var item in sorted.entries) {
...
}