Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clone a List, Map or Set in Dart

People also ask

What's the difference between a list and a Map in Dart Flutter?

List, Set, Queue are iterable while Maps are not. Iterable collections can be changed i.e. their items can be modified, add, remove, can be accessed sequentially. The map doesn't extend iterable.

How do you clone an object in darts?

Map clonedObject = JSON. decode(JSON. encode(object)); If you're using a custom class as a value in the object to clone, the class either needs to implement a toJson() method or you have to provide a toEncodable function for the JSON.


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.
2B. 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

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


With the new version of dart cloning of a Map or List become quite easy. You can try this method for making a deep clone of List and Map.

For List

List a = ['x','y', 'z'];
List b = [...a];

For Maps

Map mapA = {"a":"b"};
Map mapB = {...mapA};

For Sets

Set setA = {1,2,3,};
Set setB = {...setA};

I hope someone find this helpful.


If you are using dart > 2.3.0, You can use spread operator something like:

List<int> a = [1,2,3];
List<int> b = [...a]; // copy of a

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.


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.


Map.from() only works for 1D map.

To copy multi dimensional map without reference in dart use following method


    Map<keyType, valueType> copyDeepMap( Map<keyType, valueType> map )
    {
        Map<keyType, valueType> newMap = {};

        map.forEach
        (
            (key, value)
            {
                newMap[key] =( value is Map ) ? copyDeepMap(value) : value ;
            }
        );

        return newMap;
    }


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