Dart - For loop is changing elements of my list even when it is cloned

Viewed 31

When I access to the elements of my list in a for loop, I would like to be able to modify them without impacting the original list.

Here's a simple example :

List pairs = [
  [1,8],
  [1,6],
];

print(pairs);

List copy = List.from(pairs);

for (List pair in copy) {
  if(pair.contains(1)) {
    pair.remove(1);
  }
}

print(pairs);

The output of this is :

[[1, 8], [1, 6]]
[[8], [6]]

I expected the output to be :

[[1, 8], [1, 6]]
[[1, 8], [1, 6]]

I tried to replace List copy = List.from(pairs); with :

List copy = [...pairs]; // This
List copy = []..addAll(pairs); // Or this

Nothing is working.

The only solution I found was to do this :

List temp = List.from(pair);
if(temp.contains(1)) {
  temp.remove(1);
}

But it seems to be a bit overkill. Does anyone has another idea ?

1 Answers

As jamesdlin says, using List.from or the spread operator just creates a shallow copy of the list. Dart does not have a built-in deep copy function that I could find, but if you'll only be working with nested lists like this we can define our own pretty easily:

List<T> deepCopy<T>(List<T> list) =>
    list.map((e) => e is List ? deepCopy(e) : e).cast<T>().toList();

Here's a dartpad showing the result.

Related