Dart/Flutter – How to clone/copy a list

Note 1: in this post, I share the way we clone/copy a list of immutable elements, it’s called shallow copy. That means if your elements are mutable and you try to change the element properties, it will affect both lists (original list and copied list). I will have another post to demonstrate how to create a deep copy list later, or you can scroll down to the comment session and find my solution there.

Note 2: These approaches only work with the list of primitive types (int, String…). For the list of custom objects, I will have another article.

In this post, we will learn how to clone/copy an original list to a new list. But before that, let’s look at the below example to understand why we need to clone/copy, instead of using the original list.

void testAssignList() {
  print('Test assign list');
  var numbers = [1, 2, 3];
  var newNumbers = numbers;
  // Print the first element of new list
  print(newNumbers[0]);

  // Change original list 
  numbers[0] = 100;
  // Try to print the first element of new list again
  print(newNumbers[0]);
}
Test assign list
1
100


As you see, when we change the value of the original list (numbers – line 9), the value of the new list (newNumbers) is updated too. The reason is when we assign (using “=”), new list (newNumbers) will “refer” or “point” to the same memory of the original list (numbers). In other words, number and newNumbers are just 2 names of the same list. Changing on either list will affect the other one.

The same problem happens if we use another kind of assigned operator, like the static method castFrom()

var newNumbers = List.castFrom(numbers);


👇👇👇

In many cases, we will need to keep the original list and work on the cloned version of it. That is when we have to clone/copy, instead of assign. Dart provides some factory constructors to satisfy this requirement:

var newNumbers = List.from(numbers);
var newNumbers = List.generate(numbers.length, (index) => numbers[index]);
var newNumbers = List.of(numbers);
var newNumbers = List.unmodifiable(numbers);

All the code

void main() {
  testAssignList();

  testCreateListUsingCastFromMethod();

  print('* * * * * * * * * * ');

  testCreateListUsingFromMethod();

  testCreateListUsingGenerateMethod();

  testCreateListUsingOfMethod();

  testCreateListUsingUnmodifiableMethod();
}

void testAssignList() {
  print('Test assign list');
  var numbers = [1, 2, 3];
  var newNumbers = numbers;
  // Print value of new list
  print(newNumbers[0]);

  // Change original list
  numbers[0] = 100;
  // Try to print the value of new list again
  print(newNumbers[0]);
}

void testCreateListUsingCastFromMethod() {
  print('Create list using List.castFrom() method');
  var numbers = [1, 2, 3];
  var newNumbers = List.castFrom(numbers);
  print(newNumbers[0]);

  numbers[0] = 100;
  print(newNumbers[0]);
}

void testCreateListUsingFromMethod() {
  print('Create list using List.from() method');
  var numbers = [1, 2, 3];
  var newNumbers = List.from(numbers);
  print(newNumbers[0]);

  numbers[0] = 100;
  print(newNumbers[0]);
}

void testCreateListUsingGenerateMethod() {
  print('Create list using List.generate() method');
  var numbers = [1, 2, 3];
  var newNumbers = List.generate(numbers.length, (index) => numbers[index]);
  print(newNumbers[0]);

  numbers[0] = 100;
  print(newNumbers[0]);
}

void testCreateListUsingOfMethod() {
  print('Create list using List.of() method');
  var numbers = [1, 2, 3];
  var newNumbers = List.of(numbers);
  print(newNumbers[0]);

  numbers[0] = 100;
  print(newNumbers[0]);
}

void testCreateListUsingUnmodifiableMethod() {
  print('Create list using List.unmodifiable() method');
  var numbers = [1, 2, 3];
  var newNumbers = List.unmodifiable(numbers);
  print(newNumbers[0]);

  numbers[0] = 100;
  print(newNumbers[0]);
}
Test assign list
1
100
Create list using List.castFrom() method
1
100
* * * * * * * * * * 
Create list using List.from() method
1
1
Create list using List.generate() method
1
1
Create list using List.of() method
1
1
Create list using List.unmodifiable() method
1
1

Hope this post is useful for you! 
If you are looking for a developer or a team to build your next projects, please Drop us your request!

Tagged : / / / / /
Subscribe
Notify of
guest

15 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
Jalal
Jalal
2 years ago

I also did all ways but I get same result

Phuc
Phuc
Reply to  Jalal
2 years ago

Can you share your code?

Jalal
Jalal
Reply to  Jalal
2 years ago
class CategoryModel {
  int? id;
  bool? title;
  List<CategoryValueModel>? values;
  List<CategoryDifinitionModel>? children;

  CategoryModel(
      {this.id,
        this.title,
        this.values,
        this.children,
        });

}

class CategoryValueModel {
  int? id;
  String? value;
  String? uri;

  CategoryDifinitionValueModel(
      {this.id, this.value, this.uri});

}

List<CategoryDifinitionModel> itemsList = [];
// then i fill 'itemsList' from json api
print(items[0].values.length);
//.... will be 5 for example
// then
List<CategoryModel> testList = []..addAll(itemsList);
testList[0].values = [];
print(itemsList[0].values.length);
//.... will be 0 



Last edited 2 years ago by Jalal
Jalal
Jalal
Reply to  Jalal
2 years ago

When I update the ‘values list’ or any thing from the second list
I find the source list is updated.

Jalal
Jalal
Reply to  Jalal
2 years ago

yes… but in Flutter no. So, I found a way to convert a source list to a JSON object, then I make a new list from a JSON object, That’s work for me.

David
David
Reply to  Phuc Tran
1 year ago

and if it is a list inside another list, what would it look like?

Mahdi
Mahdi
2 years ago

thanks so much

Danny
Danny
2 years ago

Good tutorial. Thank you!

Aboud
Aboud
2 years ago

i did all ways but i get sameresult , when chang something in new array it change in old array too..(in Flutter app)–

arrayBackup = List.unmodifiable(array);
arrayBackup = List.from(array);
arrayBackup = List.of(array);
but in dartpad everything is ok !!!!!!!!!but in Flutter is Noway.
Jalal
Jalal
Reply to  Aboud
2 years ago

I also did all ways but I get same result

15
0
Would love your thoughts, please comment.x
()
x