Hasen
Hasen

Reputation: 12304

Dart Not understanding how forEach is supposed to work

I simply wanted to use forEach to set all values in a List to false, but I don't understand why it doesn't work. I created a filled list with fixed length like this:

List<bool> myList = List<bool>.filled(6, false);

Then I set one value to true:

setState(() => myList[3] = true);

Then I try to reset all values to false again, but as you can see from the print output it does not work:

setState(() {
  myList.forEach((val) => val = false);
  print(myList);
});

I/flutter (29049): [false, false, false, true, false, false]

Upvotes: 4

Views: 4638

Answers (3)

Mahdi-Malv
Mahdi-Malv

Reputation: 19190

forEach element can not modify the actual element in the list. Assume this code:

var list = [false, true, false, false];

list.forEach((item) {
    item = false;
});

print("List: $list");

The output is still:

List: [false, true, false, false]

So what you can do is using an indexed for:

for (int i=0; i < list.length; i++) {
    list[i] = false;
}

Or map it and reassign it:

var list = [true, true, false];
list = list.map((item) {
    return false;
}).toList();

You'll get:

List: [false, false, false, false]

Upvotes: 3

lrn
lrn

Reputation: 71623

As pointed out above, the forEach function does not give you write access to the list, it just provides you with the value. Changing the parameter of the forEach callback function has no effect outside of that function call, it's just changing a local variable.

To change the list, you must store to its element slots directly. Either:

for (int i = 0; i < list.length; i++) list[i] = false;

or

list.fillRange(0, list.length, false);

should do the job.

Upvotes: 1

diegoveloper
diegoveloper

Reputation: 103361

You can check the answer why you can't update the values inside forEach here: List.forEach unable to modify element?

Dart does not have variable references, all elements are passed as a reference to an object, not to a variable. (In other words, Dart is purely "call-by-sharing" like both Java and JavaScript).

That means that the e parameter to the forEach callback is just a normal local variable, and assigning to it has no effect outside the callback. The same goes for iterators: they return the value in the iterable, but it has no reference back to the iterable after that.

You can do what you want using filled method like you used to create the list.

setState(() {
  myList = List<bool>.filled(myList.length, false);
  print(myList);
});

Upvotes: 5

Related Questions