33

Code will explain all:

//modal for list
class MyModal
{
 int myField1;
 List<MyModal> adjacentNodes;
 MyModal(this.myField1)
 {
  adjacentNodes= new List<MyModal>();
 }
}

//pre code
List<MyModal> originalList = new List<MyModal>();
originalList.add(new MyModal(1,"firstBuddy"));

//copying list
List<MyModal> secondList = new List<MyModal>();
secondList.addAll(originalList);

//Modifing copy list
secondList.adjacentNodes.add(new MyModal(2,"anotherBuddy"));

//Also modifies original list
print(originalList[0].childs.length); //prints 1, it should prints 0

How can I perform changes in the second list without affecting the original list?

Brijesh Kalkani
  • 789
  • 10
  • 27
pallav bohara
  • 6,199
  • 6
  • 24
  • 45

9 Answers9

36
class MyModal {
  int myField1;
  String myField2;
  List<MyModal> adjacentNodes;
  MyModal(this.myField1,this.myField2);

  MyModal.clone(MyModal source) : 
      this.myField1 = source.myField1, 
      this.myField2 = source.myField2,
      this.adjacentNodes = source.adjacentNodes.map((item) => new MyModal.clone(item)).toList();
}

var secondList = originalList.map((item) => new MyModal.clone(item)).toList();

If a member of MyModal is of a non-primitive type like String, int, double, num, bool, then the clone() method needs to clone the instances references point to as well.

I think for your use case using immutable values is a better approach, for example with https://pub.dartlang.org/packages/built_value

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
20

you can use List.from() function. try this code:

//modal for list
class MyModal {
  int myField1;
  String name;
  List<MyModal> adjacentNodes;
  MyModal(this.myField1, this.name) {
    adjacentNodes = new List<MyModal>();
  }
}

void runCopy() {
//pre code
  List<MyModal> originalList = new List<MyModal>();
  originalList.add(new MyModal(1, "firstBuddy"));

//copying list
  List<MyModal> secondList = List.from(originalList);
  secondList.addAll(originalList);
  print(originalList);
  print(secondList);
}
mosleim
  • 654
  • 6
  • 19
  • 20
    This will only perform a shallow copy of objects, try to change the value of name in original list then print it from both of them, it will be the same. This will work fine only for simple types like int or string. So, no it should not be selected as correct answer. – hydeparkk Jan 17 '20 at 10:17
13

The recommended way is to use .toList or a list literal.

List<int> source = [1];

List<int> copied = source.toList();
List<int> copied2 = [...source];
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
7

I just used thelist2 = thelist1.toList(); and it work

Malek Tubaisaht
  • 1,170
  • 14
  • 16
7

I was having the same problem, List.from() and List.of() didn't work. I had to map the current list, thus creating a new instance.

List<CompanyBranchesDTO> get companyBranchesCopy {
  return companyBranches.map((e) =>
          CompanyBranchesDTO(id: e.id, name: e.name, isChecked: e.isChecked))
      .toList();
}

That way I have a new instance to inject where it is needed.

Luiz Filipe Medeira
  • 1,142
  • 8
  • 13
2

Change it to JSON then parse it again to object. I know it's dirty way.

(+) it works and less code. (-) it not parsing method.

Rico AW
  • 59
  • 2
1

Make this extension, put it somewhere.

import 'dart:convert';

extension ListExtensions on List {
  get() {
    return jsonDecode(jsonEncode(this));
  }
}

Basically we need to encode and decode the List so it doesn't refer to the previous List. You can use it like this:

//import your extension

List productList = ["GG FILTER 12","SK KRETEK 12"];
List newProductList = productList.get();
Daanzel
  • 987
  • 7
  • 6
0

Spread operator allow you to insert values from another list into a collection as explained in the dart language tour: https://dart.dev/guides/language/language-tour#lists So you can simply do that to avoid shallow copying:

final List<MyType> newList = [...oldList];

See this dartpad as POC:

https://dartpad.dev/191c4767abc9540c63103044038562da?null_safety=true

Arnaud Delubac
  • 759
  • 6
  • 13
-1
List<T>.addall(T) worked for me

i.e.

List<mylist>.addall(oldlist)
Markus
  • 2,265
  • 5
  • 28
  • 54
Xavier
  • 87
  • 1
  • 4
  • 2
    The answer is lacking explanation and has syntax errors which means your code will not compile. Please, before posting an answer make sure you: 1) have an explanation enough to understand your solution; 2) your solution is working; 3) good, but not required - point out the reason of the error OP gets, if possible. – Jenea Vranceanu Sep 05 '20 at 17:53