I have a list like this.
[{ a, 2 }, { b, 2 }, { c, 2 }, { d, 1 }, { e, 2 }, { f, 1 }, { g, 1 }, { h, 3 }]
I want toread this list. for example ı want to print a or print 2.
How can I do this?
This is essentially a list of maps or a list of lists. In both cases, you could simply iterate over the 'root' list and for the child, print the different values.
// list with some random maps and lists inside it
List<dynamic> myList = [{'a': 2}, ['b', 2], ...];
Now you can iterate it and, depending on the contents, print them:
for (var item in myList) {
print(item);
// depending on the type, print/process it
if (item is List) {
for (var nestedItem in item) {
... // print each nested item
}
} else if (item is Map) {
print(item.keys);
print(item.values);
print(item.entries);
}
}
Depending on your needs, you can tweak/combine the code above.
Related
I have a map that initially has empty lists as values. And a list with various data. What I want to do is to search the list for items similar to the map keys and add them as values.
This is my code:
void main() {
List list = [];
var maps= {
'A' : [],
'B' : [],
'C' : [],
};
List y = ['A','B','C','A','B','C'];
maps.forEach((key,values){
List temp =[];
for (var i in y){
if(key == i) {
list.add(i);
}
temp = list;
}
maps[key] = temp;
list.clear();
print(maps);
});
}
This is the result I get
{A: [], B: [], C: []}
And I need this result
{A: [A,A], B: [B,B], C: [C,C]}
Thank you very much for your help.
Your issue is that at no point are you directly manipulating the existing List with the matching key in your Map.
And you don't need the list or the temp variables.
var maps = {
'A': [],
'B': [],
'C': [],
};
List y = ['A', 'B', 'C', 'A', 'B', 'C'];
maps.forEach((key, value) {
for (String char in y) {
if(char == key) {
maps[key]!.add(char); // this is what adds the matching String from the list to the corresponding list in the map
}
}
});
log(maps.toString()); // {A: [A, A], B: [B, B], C: [C, C]}
I have two lists and need to get the category of each word and display it as a group.
my first list is where data is coming from.
final WordsList = [
{
'category': 'category-1',
'words': ['Happy', 'Excited', 'Playful', 'Content', 'Grateful', 'Inspired']
},
{
'category': 'category-2',
'words': ['Confused', 'Doubtful','Confused']
},
{
'category': 'category-3',
'words': ['Scared','Horrified']
},
Then the second list is from the user selection
List userSelection = [Happy, Confused, Doubtful, Scared, Horrified];
What i want to achieve is below.
Category-1
Category-2
Category-3
Happy
Confused
Scared
Doubtful
Horrified
Here is my code so far what I did was iterate the userSelection list and search the words from the word list and was able to retrieve the list but cannot figure out how to display it properly.
void getCategory() {
var wordsDisplay = [];
for (var i = 0; i < userSelection.length; i++) {
wordsDisplay.add(WordsList
.where((element) => (element["words"].contains(userSelection[i]))));
}
}
Try this out:
void main() {
List<Map<String, dynamic>> wordsList = [
{
'category': 'category-1',
'words': [
'Happy',
'Excited',
'Playful',
'Content',
'Grateful',
'Inspired'
]
},
{
'category': 'category-2',
'words': ['Confused', 'Doubtful', 'Confused']
},
{
'category': 'category-3',
'words': ['Scared', 'Horrified']
},
];
// using a set to eliminate duplicates like 'Confused' in category-2
Set<String> userSelection = {
'Happy',
'Confused',
'Doubtful',
'Scared',
'Horrified',
};
List<Map<String, dynamic>> wordsDisplay = [
for (final category in wordsList)
{
// copy category into a new map
...category,
// overwrite the 'words' key/value pair
// the items we want are the set intersection of the userSelection
// and the original words list.
'words': userSelection.intersection({...?category['words']}),
},
];
print(wordsDisplay);
}
I've got list of strings named list and list of map named type
list ['value1', 'value2']
type [{data: 'value1', isSelected: false},{data: 'value5', isSelected: false}]
I want to update isSelected value in 'type' list if value in list is equal to type.data value
I managed to do it this way
if (type != null) {
for (var l in list) {
for (var t in type) {
if (l.data == t) {
l.isSelected = true;
}
}
}
}
Is there a more decent way of doing it?
You can use for with contains and when data is found no need to continue further. Hence, break the loop.
var list = ['value1', 'value2'];
var type = [{data: 'value3', isSelected: false}, {data: 'value4', isSelected:false}]
Edit
for (object in type) {
if (list.contains(object['data'])) { // changed from indexOf as recommended in comments
object['isSelected'] = true;
break:
}
});
If you just need to know if the value of data is contained in the list array, you only need 1 loop:
var list = ['value1', 'value2'];
var type = [{data: 'value3', isSelected: false}, {data: 'value4', isSelected:false}]
for (t in type) {
if (list.contains(t.data)) { // changed from indexOf as recommended in comments
t.isSelected = true;
}
}
I have a non-primitive list which I would like to sort.
When I sort it, the UI thread is blocked and the app freezes for a few seconds.
I tried to avoid this by using dart's Isloate compute function but since the parameter sent to the compute function must be a primitive or a list/map of primitives (send method) it didn't work.
To conclude, is there any way to perform a list sort(non-primitive) without blocking the UI thread?
Edit: Clarification - I was trying to call a function through compute and I was passing a list of objects (which I got from a third party plugin) as an argument, those objects had a property of type Iterable and that caused everything to fail - make sure all the types are primitive or List/Map of primitives. With the answers I received and changing the type from Iterable to List it worked.
I'm not sure if I understood your question, but you can sort a list of non primitive elements like this:
final List<Element> elements = [
Element(id: 1),
Element(id: 7),
Element(id: 2),
Element(id: 0)
];
elements.sort((a, b) => a.compareTo(b));
// or
elements.sort((a, b) => a.id > b.id ? 1 : -1);
This would be a print(elements); output:
I/flutter ( 7351): [id: 0, id: 1, id: 2, id: 7]
And this would be the class Element
class Element {
final int id;
Element({this.id});
#override
String toString() => "id: $id";
int compareTo(Element other) => this.id > other.id ? 1 : -1;
}
Edit: To make this asynchronously, you could do this:
Future<List<Element>> asyncSort() async {
print("before sort: $elements");
elements = await compute(_sort, elements);
print("after sort: $elements");
return elements;
}
static List<Element> _sort(List<Element> list) {
list.sort((a, b) => a.compareTo(b));
return list;
}
print("before calling asyncSort(): $elements");
asyncSort();
print("after calling asyncSort(): $elements");
And this would be the output:
I/flutter ( 7351): before calling asyncSort(): [id: 1, id: 7, id: 2, id: 0]
I/flutter ( 7351): before sort: [id: 1, id: 7, id: 2, id: 0]
I/flutter ( 7351): after calling asyncSort(): [id: 1, id: 7, id: 2, id: 0]
I/flutter ( 7351): after sort: [id: 0, id: 1, id: 2, id: 7]
Edit2: If you want to send a compare function to compute, you could use a Map or a List of arguments with the list and the compare function and pass that instead of the list, because compute just takes one argument. Here is an example:
Future<List<Element>> asyncSort() async {
print("before sort: $elements");
Map args = {"list": elements, "compare": compare};
elements = await compute(_sortWith, args);
print("after sort: $elements");
return elements;
}
static List<Element> _sortWith(Map args) {
List<Element> list = args["list"];
Function(Element a, Element b) compare = args["compare"];
list.sort((a, b) => compare(a, b));
return list;
}
static int compare(Element a, Element b) {
return a.id > b.id ? 1 : -1;
}
This is how i use compute, just put all parameters to a list, then call it in a List of dynamic object:
image = await compute(getCropImage, [copyFaces, streamImg]);
imglib.Image getCropImage(List<dynamic> values) {
var face = values[0]; // copyFaces
var image = values[1]; // streamImg
}
I have the following model stored in mongodb:
{
"_id": (MongoId)
"user": "X",
"field-name-1":{
"obj-1": 12345,
"obj-2": 54321,
"obj-3": 67890,
(...)
},
"field-name-2:{
"obj-1": {"foo":"bar", "bar":"foo"},
"obj-2": {"foo":"bar2", "bar":"foo2"},
(...)
}
}
How do I find the ocurrences that contains more than 5 objects inside the "field-name-1"? Is it the same for "field-name-2"?
I can't use a variable to count the amount of objects because I upsert values inside the "field-name-1"/"field-name-2" constantly.
Thanks.
Already tried (without success):
db.summoners.find({$where: "this.['field-name-1'].length > 5"})
db.summoners.find({$where: "['field-name-1'].length > 5"})
$where should be qualified in this case:
function findMyDocument(key, value) {
var f = this[key];
if (typeof f != "object" || typeof value != "number") {
return false;
}
var count = 0;
for (var x in f) {
if (++count > value) {
return true;
}
}
return false;
}
// store above function to database for invoking
db.system.js.insert({_id:"findMyDocument", value: findMyDocument});
// apply here
db.summoners.find({$where: "findMyDocument.call(this, 'field-name-1', 5);"});
db.summoners.find({$where: "findMyDocument.call(this, 'field-name-2', 5);"});