単構造のArrayを複製する場合は、
var myArray:Array = [0,1,2,3];
var copyArray =[];
copyArray=myArray.concat();
というやりかたが昔から一般的に行われているのですが、これが多重構造の配列になってくると配下の配列が参照になってしまい、複製になりません。ぐるぐる回して変数レベルで新規配列に引き渡して複製配列を生成することも可能ですが、構造が定型じゃない場合など非常にめんどくさい。で、こんなものを発見したのメモ。
“ObjectCopy”。(ジャ~~ン)
これは元々Objectのコピーのためのクラスなのですが、多重配列もキレイに複製してくれます。
最初にObjectを複製する方法から・・・
var myObject:Object = {a:1, b:2};
var copyObject:Object = myObject;
copyObject.a = 3;
trace(myObject == copyObject);
//true
この場合はcopyObjectはmyObjectへの参照になっています。(Objectなので当然ですが・・)
これをコピーする場合は
import mx.utils.ObjectCopy;
var myObject:Object = {a:1, b:2};
var copyObject:Object = ObjectCopy.copy(myObject);
copyObject.a = 3;
trace(myObject == copyObject);
//false
次は二重配列です。concatを使用した場合
var myArray:Array = [[1, 2, 3], [2, 3, 4]];
//var copyArray:Object = ObjectCopy.copy(myArray);
var copyArray:Array = [];
copyArray = myArray.concat();
copyArray[0][0] = 5;
trace(myArray[0][0]);
//5
ネストされた配列は参照になってしまっています。
この場合にも”ObjectCopy”を使用して複製することができます。
import mx.utils.ObjectCopy;
var myArray:Array = [[1, 2, 3], [2, 3, 4]];
var copyArray:Object = ObjectCopy.copy(myArray);
copyArray[0][0] = 5;
trace(myArray[0][0]);
//1
とすることで多重構造の配列の複製を作ることができます。
ま、こういう感じでやっていくと一つのデータセットClassをベースに複数並列で派生とかできて便利なのではないか?と思いました。
あ、でも型宣言がObjectになってるからsortとかもしかしたら使えないのだろうか?
後で調べてみる。
===================================
ということで続き。
多重構造配列を”ObjectCopy.copy()”で複製する際に型が”Object”になっているのでSortができるのか?という実験。
import mx.utils.ObjectCopy;
var myArray:Array = [{key:”a”, info:[1, 2, 3]}, {key:”x”, info:[1, 2, 3]}, {key:”b”, info:[2, 3, 4]}];
var copyArray:Object = ObjectCopy.copy(myArray);
copyArray[0].info[0] = 5;
trace(myArray[0].info[0]);
copyArray.sortOn(“key”);
結果は以下のとおり。
//myArray
//[{key:”a”, info:[1, 2, 3]},{key:”x”, info:[1, 2, 3]},{key:”b”, info:[2, 3, 4]}];
//copyArray
//[{key:”a”, info:[1, 2, 3]},{key:”b”, info:[2, 3, 4]},{key:”x”, info:[1, 2, 3]}];
キチンとできているみたい。うん、OK問題なし。
ということで終了ーー。
===================================
えと、3重配列になった場合に参照になってしまうということをMk-10さんに言われたので調べてみました。
import mx.utils.ObjectCopy;
var myArray:Array = [[0, 1, [1, 2, 3]], [1, 2, [3, 4, 5]], [2, 3, [4, 5, 6]]];
var copyArray:Object = ObjectCopy.copy(myArray);
copyArray[0][2][0] = 500;
trace([myArray[0][2][0],copyArray[0][2][0]]);
//500,500
確かに参照になっている・・汗
で、この辺の対応については野中さんのサイトでカスタマイズについて書かれていましたので、リンクを張っておきます。
Macromedia Flash非公式テクニカルノート / ObjectCopy.copy()メソッドを多重配列対応に修正する
いやー、危なかった。
「ObjectCopy.copy()」への5件の返信
うを!これ思いつかなかったなぁ超便利。
過去のソースはそのままforでまわしておこう…。
オデモ
こういうの見っけましたー。
ObjectCopy.copy()の多重配列対応
http://www.fumiononaka.com/TechNotes/Flash/FN0604001.html
あら?
普通に”ObjectCopy.copy”だと参照になっちゃうの?
あれれ?間違ったこと書いちゃったかな?
やべぇw
配列内配列の場合にMk-10さんの言われていた参照の問題が発生してました。(オデがSortの方に気をとられてObject化していたので気づかなかった)
ということで野中さんのサイトへリンクを張っておきましたw