在省道中克隆一个列表、地图或集合

来自 Java 背景: “克隆”Dart ListMapSet的推荐方法是什么?

88075 次浏览

在 Java 中使用 clone()是一个棘手的问题 一,二。实际上,clone()是一个复制建构子,因此,达特 ListMapSet类型都有一个名为 .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

为了完整起见,我应该提到 dart:html Node类定义了一个 克隆()方法。


布洛赫,《 有效的爪哇》第二版,第11项。
2 文纳斯,《乔希 · 布洛克关于设计: 复制建构子与克隆》 ,2002年。引自此处 3。引自文章:

如果你读过我书中关于克隆的内容,特别是如果你读懂了字里行间的意思,你就会知道我认为克隆已经被深深地打破了。约翰 · 布洛赫

3 Dart 问题 # 6459,克隆实例(对象).

给出的答案是好的,但是要注意 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);
}

对于深度复制(克隆) ,您可以使用:

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

但可能会有一些关于性能的担忧。

这种解决方案应该会奏效:

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


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

这是一个列表,但应该工作相同的地图等,记住添加到列表,如果它的一个列表在最后

对于列表和集合,我通常使用

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

正如@kzhdev 提到的,需要注意的是 addAll()from()

[不要真的做一个克隆。他们在新的 Map/List/Set 中添加一个引用。

我通常不介意,但我会记住的。

From () 仅适用于1D map。

在省道中对 无参考复制多维地图使用以下方法


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


对我来说最好的解决办法是:

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

如果使用 dart > 2.3.0,可以使用扩展运算符,比如:

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

这就是我的解决办法,我希望它能帮到别人。

  factory Product.deepCopy(Product productToCopy) => new Product(
productToCopy.id,
productToCopy.title,
productToCopy.description,
productToCopy.price,
productToCopy.imageUrl,
productToCopy.isFavorite,
);}


随着新版本的省道克隆一个地图或列表变得相当容易。 您可以尝试使用此方法对 List 和 Map 进行深度克隆。

名单

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

为了地图

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

集合

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

我希望有人觉得这有帮助。

复制映射 < 字符串,列表 > 过滤;

 var filteredNewCopy = filtered.map((key, value) => MapEntry(key, [...value]));

没有100% 防弹的方法来制作一个精确的独立副本,但是 来自 Manish Dhruw 的回答是相当不错的。但是,它只适用于包含简单变量类型和嵌套映射的映射。

要将其扩展到其他常见集合(如 ListSet以及 它们的组合) ,可以使用下面的代码。

您实际上并不需要 DeepCopyable类,但是如果您希望使用这些函数轻松地使您自己的类具有“深度可复制性”,那么它将非常有用。

abstract class DeepCopyable{
T deepCopy<T>();
}


List<T> listDeepCopy<T>(List list){
List<T> newList = List<T>();


list.forEach((value) {
newList.add(
value is Map ? mapDeepCopy(value) :
value is List ? listDeepCopy(value) :
value is Set ? setDeepCopy(value) :
value is DeepCopyable ? value.deepCopy() :
value
);
});


return newList;
}


Set<T> setDeepCopy<T>(Set s){
Set<T> newSet = Set<T>();


s.forEach((value) {
newSet.add(
value is Map ? mapDeepCopy(value) :
value is List ? listDeepCopy(value) :
value is Set ? setDeepCopy(value) :
value is DeepCopyable ? value.deepCopy() :
value
);
});


return newSet;
}




Map<K,V> mapDeepCopy<K,V>(Map<K,V> map){
Map<K,V> newMap = Map<K,V>();


map.forEach((key, value){
newMap[key] =
value is Map ? mapDeepCopy(value) :
value is List ? listDeepCopy(value) :
value is Set ? setDeepCopy(value) :
value is DeepCopyable ? value.deepCopy() :
value;
});


return newMap;
}

正如我提到的,它显然仍然不是100% 防弹的-例如,您将丢失嵌套集合的类型信息。

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

看起来也有用

飞镖2.15

方法 -1: 建议

若要克隆多维(嵌套) List 或 Map ,请使用 Decode ()和 json.encode ()

List newList = json.decode(json.encode(oldList));
Map newMap = json.decode(json.encode(oldList));

方法二:

List newList = [...oldList];
Map newMap = {...oldMap}

方法三:

List newList = List.from(oldList);
Map newMap = Map.from(oldMap);

方法四:

List newList = List.of(oldList);
Map newMap = Map.of(oldMap);

方法五:

List newList = List.unmodifiable(oldList);
Map newMap = Map.unmodifiable(oldMap);

更多参考资料:

Https://www.kindacode.com/article/how-to-clone-a-list-or-map-in-dart-and-flutter/ Https://coflutter.com/dart-flutter-how-to-clone-copy-a-list/

这是我的解决方案,希望对你有用

class Person {
String? name;
int? age;
Person(this.name, this.age);
factory Person.clone(Person source) {
return Person(source.name, source.age);
}
}


final personList = [
Person('Tom', 22),
Person('Jane', 25),
];
final yourCopy = personList.map((p) => Person.clone(p)).toList();

如果您使用的是动态类型化数据(也就是来源于 JSON 或构建为编码为 JSON 的数据) ,您可以使用这个函数来执行深度复制:

cloneDeep(value) {
if (value is List<dynamic>) {
return value.map<dynamic>(
(item) => cloneDeep(item),
).toList();
} else if (value is Map) {
return value.map<String, dynamic>(
(key, item) => MapEntry<String, dynamic>(key, cloneDeep(item)));
}
return value;
}

最终名单 = [[] ,[]] ; Final 克隆 = list.copRange (0,list.length-1) ;