2

in https://dartpad.dartlang.org/ editor I typed below to test my issue.

based on my testing apparently list.from function only create a NEW copy when the T is not object/class

I tested list.from for List it works like charm but not class/object.

please let me know how to create a new copy of the list of T below code so that when we change the list in one place, the other place does not get change.

thanks

void main() {
  List<Status> statuses = <Status>[
    Status(name: 'Confirmed', isCheck: true),
    Status(name: 'Cancelled', isCheck: true),
  ];
  print('statuses = ${statuses.toList().map((x) => x.name + '=' + x.isCheck.toString())}');

  //this supposed to create a new list of T but apparently only work for non-object
  List<Status> otherStatuses =  new List<Status>.from(statuses);

  print('otherStatuses= ${otherStatuses.toList().map((x) => x.name + '=' + x.isCheck.toString())}');

 otherStatuses.singleWhere((x)=>x.name=='Cancelled').isCheck=false;

  print('after the changes only on otherStatuses');
  print('statuses = ${statuses.toList().map((x) => x.name + '=' + x.isCheck.toString())}');

  print('statuses2 = ${otherStatuses.toList().map((x) => x.name + '=' + x.isCheck.toString())}');

  print('why the original status (cancelled) equal to false?');

}


class Status {
  String name;
  bool isCheck;

  Status({
    this.name,
    this.isCheck,
  });
}

Hendra
  • 23
  • 1
  • 5
  • 1
    You are getting a new copy of the _list_, you aren't getting a new copy of the objects _within_ the list. There is no general way to implement a deep collection copy, you must implement the copy for the elements within the list yourself. – Nate Bosch Jan 11 '19 at 22:57

3 Answers3

8

To create a list of new elements use the map() function you already used for other purpose in your code:

List<Status> otherStatuses = statuses.map((status)=>Status(name:status.name, isCheck:status.isCheck)).toList()
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
shadowsheep
  • 14,048
  • 3
  • 67
  • 77
  • 1
    I think this answer is workaround kind of but it works, what if the T has so many properties, is there a better way to solve this? because of course, I have simplified the properties in a real application is more complex than this. – Hendra Jan 12 '19 at 00:38
  • @Hendra well, I would not use the term "workaround". I would use this term for something that is expected to work in a way but it doesn't. Here you are using the [`List.from()`](https://api.dartlang.org/stable/2.1.0/dart-core/List/List.from.html) methods that builds a list from the elements of the iteratrable passed and these elements are passed by reference so they end up to be the same objects. You need to forge a brand new element from the element passed. Where you decide to do it (in the map function, on a top level function or in a instance clone method) that it's up to you. – shadowsheep Jan 12 '19 at 09:16
  • This doesn't work. It shouldn't have a green check. – Eli Whittle Aug 05 '19 at 18:13
  • @EliWhittle why do you say that? Here's a [gist](https://dartpad.dartlang.org/3e95a5d076d07f3c1ed8d70cab34127c) proving it works. – shadowsheep Aug 05 '19 at 18:29
0

There are different threads about the same topic find multiple solutions. In the dart repository they had a discussion about a clone function as well and decided not to implement it and they a issue for it.

Knupper
  • 44
  • 4
  • Sorry maybe I've edited to much, but still your solution with `new List.from(statuses)` doesn't work. If you make final fields, than you cannot change them, I think I'm missing something... – shadowsheep Jan 11 '19 at 22:38
  • You are right, it needs some more changes, i added them to the original post – Knupper Jan 11 '19 at 23:10
0

you can also use

List<Status> otherStatuses = List<Status>.generate(statuses.length,(i) => Status(name: statuses[i].name , isCheck:statuses[i].isCheck));

regarding WHY?

Your code did not work simply because the new otherStatuses list was referencing the same Status(s) object(s) So when you was changing it, it also change in the original statuses list because it is the same object.

Saed Nabil
  • 6,705
  • 1
  • 14
  • 36