Dart Can't change map value from initial map
I have this code :
void main() {
Map tabtest = {
'1' : {
'd' : 'one'
}
};
Map tabtest1 = {};
tabtest.forEach((cle1, val1) {
val1['d']='two';
tabtest1['cle1']=val1;
});
Map tabtest2={};
tabtest.forEach((cle2, val2) {
val2['d']='three';
tabtest2['cle2']=val2;
});
print(tabtest);
print(tabtest1);
print(tabtest2);
}
This code display :
{1: {d: three}}
{1: {d: three}}
{1: {d: three}}
But I want different value from tabtest1 and tabtest2 like :
tabtest1 = {1: {d: two}}
tabtest2 = {1: {d: three}}
Can help me?
Thanks.
There were a couple of problems:
you were actually using the same sub-map {'d': 'one'} in all three versions, instead of creating three seperate maps. The easiest way to copy a Map is to use Map secondMap = Map.from(firstMap). Beware though - this will only copy the first 'level' of the map. See this question for more information
you were using the string 'cle1' instead of it's value, so tabtest1['cle1'] should have been tabtest1[cle1]
void main() {
Map tabtest = {
'1' : {
'd' : 'one'
}
};
Map tabtest1 = {};
// For each map entry in tabtest
tabtest.forEach((cle, val) {
// First COPY the sub-map. If we don't make a copy, we end up
// changing the sub-map in both tabtest and tabtest2
Map val1 = Map.from(val);
// Then we can update the value in our new sub-map:
val1['d']='two';
// And set this as the key '1' in tabtest1
tabtest1[cle]=val1;
});
Map tabtest2={};
tabtest.forEach((cle, val) {
Map val2 = Map.from(val);
val2['d']='three';
tabtest2[cle]=val2;
});
print(tabtest);
print(tabtest1);
print(tabtest2);
}
{1: {d: one}}
{1: {d: two}}
{1: {d: three}}
Related
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
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));
map1 = { "a": 10, "b": 6 },
map2 = { "a": 10, "b": 6, "c": 7, "d": 8 };
Flutter:How to merge two objects and sum the values of the same key?
Do forEach on the longest map and check if the small map contains the key if it does then update the value with the sum or add the new.
map2.forEach((key, value) {
if (map1.containsKey(key)) {
map1[key] = value + map1[key]!;
} else {
map1[key] = map2[key]!;
}
});
map1 will be the final result.
So, if you want to combine/merge the two maps use this code this answer:
final firstMap = {"1":"2"};
final secondMap = {"2":"3"};
final thirdMap = { // here simple adding element to map
...firstMap,
...secondMap,
};
but if you want to make sum and merge use this :
map2.forEach((k, v) {
if (map1.containsKey(k)) { // check if the map has more then 2 values as the 1st one
map1[k] = v + map1[k]!; // if yes so make the some
} else {
map1[k] = map2[k]!; // if no then add the values to map
}
});
as MEET Prajapati asnwer.
Through Flutter I want to add a Map element in Firestore.
Instead of fetching the whole map and replacing it with the added element is it possible to directly add a new key and value?
Example:
Map = { '2020-05-21' : true } -- Add --> Map = { '2020-05-21' : true, '2020-05-22': true }
This is how I tried to do this but without any success.
return collection.document('id').updateData({'map.$date' : true});
Use this approach:
final ref = Firestore.instance.document('collection_id/document_id');
await ref.updateData({
'field.key2': 'value2',
});
Since I am not having an idea about how your data looks like on server, I tested this one and it worked.
Edit:
// initial work
var ref = Firestore.instance.document('Employees/54G...Naf');
var initialData = {
'date_1': '1',
};
await ref.setData({
'busy_map': initialData,
});
// updated work
var updatedData = {
'busy_map.date_2': '2',
};
await ref.updateData(updatedData);
How to search a list of a class object with one of its property matching to any value in another list of strings
I am able to get filtering based on a single string , but not on a list of strings
final List<shop_cart.ShoppingCart> cartprd = snapshot.documents
.map((f) => shop_cart.ShoppingCart.fromMap(f.data))
.toList();
List<SomeClass> list = list to search;
List<String> matchingList = list of strings that you want to match against;
list.where((item) => matchingList.contains(item.relevantProperty));
If the number of items in list is large, you might want to do:
List<SomeClass> list = list to search;
List<String> matchingList = list of strings that you want to match against;
final matchingSet = HashSet.from(matchingList);
list.where((item) => matchingSet.contains(item.relevantProperty));
Or else just always store the matching values as a hashset.
In case if you want to check for a value in a list of objects . you can follow this :
List rows = [
{"ags": "01224", "name": "Test-1"},
{"ags": "01224", "name": "Test-1"},
{"ags": "22222", "name": "Test-2"},
];
bool isDataExist(String value) {
var data= rows.where((row) => (row["name"].contains(value)));
if(data.length >=1)
{
return true;
}
else
{
return false;
}
}
you can put your own array of objects on rows . replace your key with name . you can do your work based on true or false which is returned from the function isDataExist
As of today, you can't.
(A side note : You can use .where, .singleWhere, .firstWhere. This site explains various list/array methods.)
You can simply use List.where() to filter a list
final List<shop_cart.ShoppingCart> cartprd = snapshot.documents
.where((f) => shop_cart.ShoppingCart.contains(f.data));
var one = [
{'id': 1, 'name': 'jay'},
{'id': 2, 'name': 'jay11'},
{'id': 13, 'name': 'jay222'}
];
int newValue = 13;
print(one
.where((oldValue) => newValue.toString() == (oldValue['id'].toString())));
OUTPUT : ({id: 13, name: jay222})
store output in any variable check if variable.isEmpty then new value is unique either
var checkValue = one
.where((oldValue) => newValue.toString() == (oldValue['id'].toString()))
.isEmpty;
if (checkValue) {
print('Unique');
} else {
print('Not Unique');
}
OUTPUT : Not Unique