web-dev-qa-db-fra.com

Cloner une liste, une carte ou un ensemble dans Dart

Provenant d'un Java background: quelle est la méthode recommandée pour "cloner" un Dart List, Map et Set?

49
Patrice Chalin

L'utilisation de clone() dans Java est délicate et discutable1,2. En effet, clone() est un constructeur de copie et pour cela, les types Dart List, Map et Set ont chacun un constructeur nommé nommé .from() qui effectue une copie superficielle ; par exemple. compte tenu de ces déclarations

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

vous pouvez utiliser .from() comme ceci:

  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');

Notez que List.from() accepte plus généralement un itérateur plutôt qu'un simple List.

Par souci d'exhaustivité, je dois mentionner que la classe Dart:htmlNode définit une méthode clone () .


1 J. Bloch, " Java efficace " 2e éd., Point 11.
2B. Venners, " Josh Bloch sur la conception: copier le constructeur contre le clonage ", 2002 . Référencé d'ici3. Citation de l'article:

Si vous avez lu l'article sur le clonage dans mon livre, surtout si vous lisez entre les lignes, vous saurez que je pense que le clone est profondément cassé. --- J.Bloch

3Dart Issue # 6459, instance de clone (objet) .

41
Patrice Chalin

Pour les listes et les ensembles, j'utilise généralement

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

La mise en garde, comme le mentionne @kzhdev, est que addAll() et from()

[Ne] faites pas vraiment de clone. Ils ajoutent une référence dans la nouvelle carte/liste/ensemble.

Cela me convient généralement, mais je garderais cela à l'esprit.

7
mr.musicman

Cette solution devrait fonctionner:

Liste liste1 = [1,2,3,4];

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

C'est pour une liste mais devrait fonctionner de la même manière pour une carte, etc., n'oubliez pas d'ajouter à la liste si c'est une liste à la fin

2
CodeMemory

Map.from () ne fonctionne que pour la carte 1D pour la carte multidimensionnelle


    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;
    }

0
Manish Dhruw

La réponse donnée est bonne, mais soyez conscient du constructeur generate qui est utile si vous voulez "agrandir" une liste de longueur fixe, par exemple:

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);
}
0
Dan Field

Pour une copie complète (clone), vous pouvez utiliser:

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

mais il peut y avoir quelques inquiétudes concernant les performances.

0
karianpour

Meilleure solution pour moi List temp = {1,2,3,4} List platforms = json.decode(json.encode(parent.platforms));

0
Serg