如何克隆一个字典(以及其内容)?

3

我花了一些时间在谷歌上寻找克隆字典的方法,并找到了一些选项,但它们都没有起作用。其中一个是使用 byteArray,只有在您注册涉及的所有类并且您的类具有默认值的构造函数参数时才有效 <- 在我的情况下不是选择。

另一个是仅针对第一个值进行复制的副本,如下:

private function clone(original:Dictionary):Dictionary {
    var cloned:Dictionary = new Dictionary();
    for(var key:Object in original) {
        cloned[key] = original[key];
    }
    return cloned;
}

但是,它不会克隆主字典中的字典。

您知道如何完美地克隆给定的字典吗,即使它内部有另一个字典?

谢谢。

1个回答

1
创建一个递归函数,检查元素类型,如果它们本身是字典,则继续递归和复制。
类似以下代码(未经测试):
private function clone(original:Dictionary):Dictionary {
    var cloned:Dictionary = new Dictionary();
    for(var key:Object in original) {
      if( original[key]  is Dictionary)
         cloned[key] = clone(original[key]);
      else
         cloned[key] = original[key];
    }
    return cloned;
}

编辑:

似乎适用于像这样简单的嵌套字典:

var dic:Dictionary = new Dictionary();
dic["test"] = 5;
dic["otherDic"] = new Dictionary();
dic["otherDic"]["foo"] = 1;
dic["otherDic"]["bar"] = "bar";

var copy:Dictionary = clone(dic);

dic["test"] = 0;
dic["otherDic"]["foo"] = 0;
dic["otherDic"]["bar"] = "changed";
    //copy doesn't change, copy and dic are different dictionaries

它不起作用,也没有抛出任何错误,但它们仍然是同一个对象。 - Artemix
@sch 你是正确的,如果字典中保存的不仅仅是简单类型的对象,那么它们需要被正确地复制。这对于简单类型是有效的。 - Barış Uşaklı
我创建自定义对象的数组,然后将它们放入字典中,当我循环遍历字典并使用removeChild时,它们被删除了。但是,如果我手动创建对象,就可以正常工作。从中我理解到这些对象是同一个对象,而不是副本。 - Artemix
@Artemix 你可以用一个克隆函数来替换 cloned[key] = original[key]; 这一行,或者让类拥有一个克隆函数,该函数返回一个新的实例,复制它们的属性。 - Barış Uşaklı
@Baris,问题在于字典的内容(而不是内部的字典)是原始类型。如果你使用Sprite而不是int或string,它将无法工作。 - Artemix
@Artemix 如果你只存储Sprites,那么你可以轻松地创建一个复制Sprites的函数,并使用它来代替cloned[key] = original[key]。例如:cloned[key] = cloneSprite(original[key]); 如果你有一堆不同类型的对象,那么我建议你从一个共同的基类中扩展它们,并让它们各自拥有一个clone函数,可以像这样调用:cloned[key] = original[key].clone(); clone函数将简单地创建一个新实例并复制Sprite或其他对象的属性。 - Barış Uşaklı

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接