How to get the length of map values flutter - flutter

Map<String, bool> _toDos = {
'case1': true,
'case2': false,
'case3': false,
'case4': false,
'case5' : false
};
Say I have a map object like this and I want to get the length of strings that contains "true" values. How do I do so with flutter?
_toDos.length gives me the length of the map but I want to get the length of items that contain only "true" values.

_todos.values.where((element) => element == true).length

Related

How can I CORRECTLY append map array to firestore?

I want to add Map<> data to my firestore database with code :
Map<String, Object> prop = {
'read' : true,
'vote_left' : false,
'vote_right' : false,
};
Map<String, Object> attended_topic =
{
received_id:prop
};
FirebaseFirestore.instance.collection('userinfo').doc(user_now!.uid)
.update({"attended_topic": FieldValue.arrayUnion([attended_topic])});
What I expected is this.
attended_topic
topicId_0
read : true
vote_left : false
vote_right : false
But I got something unexpected.
attended_topic
0
topicId_0
read : true
vote_left : false
vote_right : false
I never expected that new category '0' appearing and donot know why. Since the atabase has other properties so I thought using update() rather than set() is adequate. Please somebody tell my why this happens.
From the docs
FieldValue.arrayUnion adds elements to an array but only elements not already present.
So {"a": FieldValue.arrayUnion([b])} adds b variable to the Array a.
To solve your problem, just remove FieldValue as shown below.
FirebaseFirestore.instance
.collection('userinfo')
.doc(user_now!.uid)
.set({"attended_topic": attended_topic}, SetOptions(merge: true));
// use set method to add new data (not update)
// or
FirebaseFirestore.instance.collection('userinfo').doc(user_now!.uid).set(
{
'attended_topic': {
received_id: {
'read': true,
'vote_left': false,
'vote_right': false,
}
}
},
SetOptions(merge: true),
);
I solved this problem referring Peter's solution and changing it slightly.
FirebaseFirestore.instance.collection('userinfo').doc(user_now!.uid)
.set({"attended_topic": attended_topic}, SetOptions(merge: true));

Hello there, how to check which lists in a class have expired time element in them?

In a class I have lists, in those lists I have maps, each map has 'interval' and 'time' element, I want to check which of those 'time' elements have expired and then pass those lists to further sorting according to interval (this sorting thing is working already), just not sure how to check which lists have expired 'time' in them?
In the code I have marked with //TODO part that is missing
Thank you
class QuizBrain {
List<Map<String, dynamic>> products = [
{
'id': 24,
'interval': 10000,
'time': '2021-12-14 20:37:21.190473',
},
{
'id': 36,
'interval': 20000,
'time': '2020-11-14 20:37:21.190453',
},
{
'id': 48,
'interval': 30000,
'time': '2020-12-14 20:37:21.190453',
},
];
min() {
//TODO need to set condition to check which lists 'time' is expired, then i pass those that 'time is expired to further sorting beneath
if (products != null && products.isNotEmpty) {
products.sort((a, b) => a['interval'].compareTo(b['interval']));
//print(products);
return (products.first['id']);
}
}
}
You should be able to convert the time attributes into DateTime objects and compare them to now using compareTo:
final now = DateTime.now();
final expired = products.where((item) {
final itemTime = DateTime.parse(item["time"]);
return itemTime.compareTo(now) < 0;
});
Then if I've read your question correctly you just need to replace products with expired in your if statement.
This is from the docs of compareTo():
this.compareTo(other)
Compares this DateTime object to [other], returning zero if the values are equal.
Returns a negative value if this DateTime [isBefore] [other].
It returns 0 if it [isAtSameMomentAs] [other], and returns a positive value otherwise (when this [isAfter] [other]).

Dart how do I find the index of true value in the list

I have list List<bool> _selections = [false, true, false]; and this list may change only one can be true
How do I know which index is true ?
you can use indexWhere
_selections.indexWhere((value) => value)
You can try indexWhere() method.
_selections.indexWhere((ele) => ele);
See more
while the above answer are correct and simpler you can also use a good old foreach loop like this:
for (var elements in _selections) {
if (elements == true) {
print(elements);
}
}

How to search a list of Object by another list of items in dart

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

Dart how to access second dimension in multidimensional map

I can manage to access the first dimension with mymap['status'] but I tried to access the second dimension with mymap['status'].start or mymap['status']['start'] but neither work.
Also I don't see why mymap.status doesn't work for the first dimension?
const mymap = {
'status': {
'start': ['Start', 'ok', 'go'],
},
'update': {
'now': ['Start', 'ok', 'go'],
},
'time': [
['20', '10s', '5s'],
['45', '30s', '15s']
]
};
Also not sure whether this map should have the data type Map or not but with it I get no error signal with mymap['status'].start but upon executing the code it throws the error Class '_ImmutableMap<String, List<String>>' has no instance getter 'start'
To fix your issue use a static type Map after const , like this :
const Map mymap = {
'status': {
'start': ['Start', 'ok', 'go'],
},
'update': {
'now': ['Start', 'ok', 'go'],
},
'time': [
['20', '10s', '5s'],
['45', '30s', '15s']
]
};
print(mymap['status']['start']);
You can run the code if you want https://dartpad.dartlang.org/20eab4288fbf688c6517365b89fc2b22
You look up values for keys in a Dart Map using map[key]. If the key is a string, that would be mymap["status"]. You cannot use mymap.status because map keys are completely separate from class members. That's why you can do both map["length"] and map.length and get different results.
In your example, the static type of mymap is inferred to be Map<String, Object>.
This is inferred because the values of your map are either Map<String, List<String>> (for "status" and "update") or List<List<String>> (for "time"). The only common supertype of Map and List is Object, so your map is a Map<String, Object>.
When you then write mymap['status'] you get an expression with static type Object, and you are not allowed to do ['start'] on that (Object does not have an [] operator).
If you type your variable as Map<String, dynamic>, then you are allowed to do mymap['status']['start']. The final index operation is a dynamic invocation, which comes at some run-time cost.
Alternatively, you can do (mymap['status'] as Map<String, List<String>>)['start'] which casts the looked-up value to a map of the correct type, and then does a well-typed lookup on the that map.