Я создаю простую функцию резервного копирования/отмены и не умею правильно клонировать массив для размещения в резервной копии. Я попытался использовать slice()
и рекурсивную функцию для "глубокого клонирования", но либо клонированный массив остается копией последнего состояния, либо не клонирует все элементы массива.
Я использую Вавилон.
constructor(config) {
this.all = [];
this.all.colors = [5,7];
this.all.sprites = [];
this.all.current_sprite = 0;
this.all.width = config.sprite_x;
this.all.height = config.sprite_y;
this.backup = [];
this.backup_position = 0;
}
Глубокий клон версии 1 (не работает)
save_backup() {
this.backup.push(this.deepClone(this.all));
this.backup_position ++;
console.log(this.backup);
}
deepClone(arr) {
var len = arr.length;
var newArr = new Array(len);
for (var i=0; i<len; i++) {
if (Array.isArray(arr[i])) {
newArr[i] = deepClone(arr[i]);
} else {
newArr[i] = arr[i];
}
}
return newArr;
}
Версия 2 slice()
(не работает).
save_backup() {
this.backup.push(this.all.slice());
this.backup_position ++;
console.log(this.backup);
}
Массив содержит все виды данных: целые числа, массивы, объекты, например
colors : (2) [5, 7]
config : {setting: "c64", sprite_x: 24, sprite_y: 21, colors: Array(16), zoom: 20, …}
Что я делаю неправильно? Большое спасибо за вашу помощь.
Вы можете использовать операторы распространения Array.map и Array для клонирования 2D-массива следующим образом:
const arr1 = [
[ 'a', 'b' ],
[ 'r', 's' ]
];
function clone2D(a) {
return a.map(o => [...o]);
}
const arr2 = clone2D(arr1);
arr2.push(['z']); // add el to outer
arr2[0].push('q');// add el to inner
console.log(JSON.stringify(arr1));
console.log(JSON.stringify(arr2));
Обратите внимание, что строковые элементы в массиве не клонируются в этом примере, поэтому строки являются точными, но объекты все равно могут столкнуться с проблемами, поскольку они будут содержать одну и ту же ссылку.
map
по двумерному массиву, а затем соединить весь массив?