Клонировать список, карту или установить в дротик

Исходя из фона Java: какой рекомендуемый способ "клонировать" Dart List, Map и Set?

Ответ 1

Использование clone() в Java сложно и сомнительно 1,2. По сути, clone() является конструктором копирования, и для этого каждый из типов Dart List, Map и Set имеет именованный конструктор с именем .from() который выполняет поверхностное копирование; например, учитывая эти заявления

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

Вы можете использовать .from() следующим образом:

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

Обратите внимание, что List.from() общем случае принимает итератор, а не просто List.

Для полноты картины следует упомянуть, что класс Node dart:html определяет метод clone().


1 Дж. Блох, "Эффективная Ява", 2-е изд., П. 11.
2Б. Веннерс, "Джош Блох о дизайне: копирование конструктора и клонирование", 2002. Ссылка отсюда 3. Цитата из статьи:

Если вы читали статью о клонировании в моей книге, особенно если вы читаете между строк, вы будете знать, что я думаю, что клон глубоко сломан. ---J.Bloch

3Dart Issue # 6459, экземпляр клона (объект).

Ответ 2

Для списков и наборов я обычно использую

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

Предупреждение, как упоминает @kzhdev, заключается в том, что addAll() и from()

[Не] на самом деле не сделать клон. Они добавляют ссылку в новую карту/список/набор.

Это обычно хорошо для меня, но я бы помнил об этом.

Ответ 3

Это решение должно работать:

Список list1 = [1,2,3,4];

Список list2 = list1.map((element) => element).toList();

Это для списка, но должно работать так же для карты и т.д., не забудьте добавить в список, если это список в конце

Ответ 4

Данный ответ хорош, но помните о конструкторе generate который полезен, если вы хотите "увеличить" список фиксированной длины, например:

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

Ну, в дартс 2.3 вы можете просто написать [...yourList] как оператор распространения JavaScript

Ответ 6

Для глубокого копирования (клонирования) вы можете использовать:

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

но могут быть некоторые опасения по поводу производительности.