Iterate through list and list of map - flutter

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;
}
}

Related

Flutter: filter a List<Map<String, dynamic>> to only contain certain items

I have a list of maps where one of the fields in the map is a boolean called "completed". I want to be able to filter the map so that I only get the items for which "completed" is true or false. My current code is the following:
try {
String? email = FirebaseAuth.instance.currentUser!.email;
for (int i = startingIndex; i < endingIndex; ++i) {
var doc = await FirebaseFirestore.instance
.collection(email!)
.doc("goals")
.collection(Utils.goalsCategoriesDropdownItems[i])
.get();
if (doc.size > 0) {
allData.addAll(doc.docs.map((doc) => doc.data()).toList());
}
}
allData.sort(((a, b) {
Timestamp one = a["dueDate"];
Timestamp two = b["dueDate"];
return one.compareTo(two);
}));
return allData;
}
but I don't want to return allData, I want to filter and see if all the items are true or false, so I want something like this:
if (completed == true) {
allData.map((e) => e["completed"] == true);
} else {
allData.map((e) => e["completed"] == false);
}
return allData;
It is not entirely clear what your expected outcome is, but here are two possibilities:
a) If you want to check if every Map in your List has the key completed with a value of true you can use every:
return allData.every((e) => e["completed"] === true)
b) If you want to have a list containing only Maps which contain the key completed with a value of true you can use where:
return allData.where((e) => e["completed"] === true)

override object properties in createAsyncThunk method

I have a function like this
export const fetchChildrenNews = createAsyncThunk('news/fetch1', async ([item, news]) => {
const res = await Promise.all(item.kids.map(id => {
let url = `https://hacker-news.firebaseio.com/v0/item/${id}.json?print=pretty`;
return fetch(url);
}));
const jsons = await Promise.all(res.map(r => r.json()));
let users = {...item, kids: jsons};
item.kids = []//doesn't work
item.id = 0 //doesn't work
//I want to find a branch in the original tree and replace it
const tree = (obj) => {
for (let key in obj) {
if (key === "id" && obj[key] === users.id) {
obj = users;
}
if (key == "kids") {
tree(obj);
}
}
}
tree(item);
where item is a nested object record: {by: 'nullzzz', descendants: 47, id: 28808556, kids: Array(13), score: 117}. kids property contains array of ids and in the users variable it becomes an array of records. and my goal change record.kids = [0, 7, 14] to record.kids = users ([{by: '...', id:4848,..], [{by: 'adasd'], [{by: 'zzz}] ). the variable news is a whole tree while item its branches.
I just started working with the toolkit, so I don't fully understand this
Since item is probably an object from your Redux store, that thunk would try to modify a reference to your store - and modifying the store is only allowed in reducers.
Generally, you should be doing logic like this in reducers, not in a thunk.
So, do
export const fetchChildrenNews = createAsyncThunk('news/fetch1', async ([item, news]) => {
const res = await Promise.all(item.kids.map(id => {
let url = `https://hacker-news.firebaseio.com/v0/item/${id}.json?print=pretty`;
return fetch(url);
}));
const jsons = await Promise.all(res.map(r => r.json()));
return jsons
})
and then in your slice, add the logic:
builder.addCase(fetchChildrenNews, (state, action) => {
const jsons = action.payload
// here, do not modify `items`, but modify `state` - I would assume `items` is somewhere in here anyways?
})

Add/Update list of K,V pair to empty declared map = List<Map<dynamic, dynamic>>

I have and empty map, Map optionSelection = {};
And on every button click I want to add list of K,V pair map to optionSelection map.
Format in which I want to add Map.
{
"quiz_id": selectedOption,
"ques_id": questionId,
"user_ans_id": selectedOption,
}
In above Key and Value pair, in "ques_id": questionId -> questionId will be unique, So I want to check if the value already exist, if YES then I want to update the "user_ans_id": selectedOption value or else I want to add new list of K,V pair.
Below is the code I tried
final quesExist = optionSelection.containsValue(questionId);
if (quesExist) {
optionSelection.putIfAbsent(
"ques_id",
() => optionSelection.addAll(
{
"quiz_id": selectedOption,
"ques_id": questionId,
"user_ans_id": selectedOption,
},
),
);
} else {
optionSelection.addAll(
{
"quiz_id": selectedOption,
"ques_id": questionId,
"user_ans_id": selectedOption,
},
);
}
Hope I was able to explain my issue, Thank you in advance.
after a week of struggle and many tweaks in code, here is the final solution for above query.
// Declared empty List<Map>
List<Map> optionSelection = [];
// Variable to store bool value, if the question id exist
var questionExist;
// Feed the map in below form
Map<String, dynamic> userSelection = {
"quiz_id": widget.quizId,
"ques_id": questionId,
"user_ans_id": selectedOption,
};
// Check if the Ques Id Exist in List<Map> optionSelection
questionExist = optionSelection.any((map) => map.containsValue(questionId));
// Check using if else condition, if Ques Id exist, then run the forLoop,
// to iterate in List<Map>, else add a new Set of Map to the List<Map>
if (questionExist == true) {
print("If triggered");
for (var map in optionSelection) {
if (map.containsValue(questionId)) {
map.update("user_ans_id", (dynamic val) => selectedOption);
}
}
} else {
print("Else triggered");
optionSelection.add(userSelection);
}

flutter array of items showing error in method

I want to print the index of array element as another array. I have array list name btns. It contains the value is true or false. I want the index of element having true. here my code is
List<bool> btn = [true, false, true, false, false, false, false];
Map<int, bool> map2 = btn.asMap();
var arr = new List<int>();
map2.forEach((key, value) {
if (value) {
print(key);
arr.add(key);
}
});
print(arr);
It is printin [0,2]. And showing correct results. But when I put in method. It showing error.
List<int> getbtnsInArray() {
Map<int, bool> map2 = btn.asMap();
var arr = new List<int>();
map2.forEach((key, value) {
if (value) {
print(key);
arr.add(key);
}
});
return arr;
}
print (getbtnsInArray);
It showing the error is Closure: () => List from Function 'getbtnsInArray':.
I don't know the reason. Please help me to find the answer.
You need to add brackets to call the method.
print(getbtnsInArray());

Can object properties be used as function parameters?

I have a class with several Boolean properties:
class aTest {
String name;
bool twoGroups;
bool continuous;
bool parametric;
bool covariates;
bool paired;
aTest(
{this.name,
this.twoGroups,
this.continuous,
this.parametric,
this.covariates,
this.paired});
} //end aTest
I also have a list with instances of aTest:
List<aTest> testList = [
aTest(
name: "independent samples t-test",
twoGroups: true,
continuous: true,
parametric: true,
covariates: false,
paired: false),
//followed by a bunch of similar objects
]
Elsewhere in my app I filter the List<aTest> with procedures like:
void isParametric(bool value) {
List<aTest> newList = [];
for (aTest test in testList) {
if (test.parametric == value || test.parametric == null) {
newList.add(test);
}
}
testList = newList;
}
void isTwoGroups(bool value) {
List<aTest> newList = [];
for (aTest test in testList) {
if (test.twoGroups == value || test.twoGroups == null) {
newList.add(test);
}
}
testList = newList;
}
(I don't know whether this is the best way to filter and remove objects from the List.) All that differs among these procedures is an object property, e.g., test.parametric and test.twoGroups in the code above.
Is there a way to refactor the code? Something like
void filter (aBooleanPropertyGoesHere, bool value)
You can simply filter with the lists with one liner by where method.
var parametricList = testList.where((i) => (i.continuous && i.parametric == null)).toList()
var twoGroupsList = testList.where((i) => (test.twoGroups == value || test.twoGroups == null)).toList()
Something like this https://dartpad.dev/79a7e9aa5882af745b6ff2cb55815921
For detailed explanation check out the documentation