Clone a List, Map or Set in Dart

泄露秘密 提交于 2019-12-18 04:32:35

问题


Coming from a Java background: what is the recommended way to "clone" a Dart List, Map and Set?


回答1:


Use of clone() in Java is tricky and questionable1,2. Effectively, clone() is a copy constructor and for that, the Dart List, Map and Set types each have a named constructor named .from() that perform a shallow copy; e.g. given these declarations

  Map<String, int> numMoons, moreMoons;
  numMoons = const <String,int>{ 'Mars' : 2, 'Jupiter' : 27 };
  List<String> planets, morePlanets;

you can use .from() like this:

  moreMoons = new Map<String,int>.from(numMoons)
    ..addAll({'Saturn' : 53 });
  planets = new List<String>.from(numMoons.keys);
  morePlanets = new List<String>.from(planets)
    ..add('Pluto');

Note that List.from() more generally accepts an iterator rather than just a List.

For sake of completeness, I should mention that the dart:html Node class defines a clone() method.


1 J. Bloch, "Effective Java" 2nd Ed., Item 11.
2 B. Venners, "Josh Bloch on Design: Copy Constructor versus Cloning", 2002. Referenced from here3. Quote from the article:

If you've read the item about cloning in my book, especially if you read between the lines, you will know that I think clone is deeply broken. ---J.Bloch

3 Dart Issue #6459, clone instance(object).




回答2:


For lists and sets, I typically use

List<String> clone = []..addAll(originalList);

The caveat, as @kzhdev mentions, is that addAll() and from()

[Do] not really make a clone. They add a reference in the new Map/List/Set.

That's usually ok with me, but I would keep it in mind.




回答3:


This solution should work:

List list1 = [1,2,3,4];

List list2 = list1.map((element)=>element).toList();

It's for a list but should work the same for a map etc, remember to add to list if its a list at the end




回答4:


The given answer is good, but be aware of the generate constructor which is helpful if you want to "grow" a fixed length list, e.g.:

List<String> list = new List<String>(5);
int depth = 0; // a variable to track what index we're using

...
depth++;
if (list.length <= depth) {
  list = new List<String>.generate(depth * 2,
      (int index) => index < depth ? list[index] : null,
      growable: false);
}



回答5:


For deep copy (clone), you can use :

Map<String, dynamic> src = {'a': 123, 'b': 456};
Map<String, dynamic> copy = json.decode(json.encode(src));

but there may be some concerns about the performance.



来源:https://stackoverflow.com/questions/21744480/clone-a-list-map-or-set-in-dart

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!