如何"undo" 一个删除的元素拼接?

How to "undo" a deleted element with splice?

当我有一个数组时,我使用 splice 删除数组的最后一个元素。是否有机会创建一个按钮,当我单击它时,它会撤消已删除的操作?比如在写代码的时候用Ctrl+Z 就可以及时跳回?这意味着将删除的元素及其所有特征还给我?

如果只需要一级undo,删除前复制数组即可。如果用户想要 "undo" 然后将数组恢复到它以前的化身。

var arr = [1,2,3,4,5,6];
var tempArr;

function removeThing(arr, index) {
   tempArr = arr;
   arr.splice(index, 1);
}

function undo() {
    arr = tempArr;
}

Array.splice 允许你删除或插入元素,它也returns 删除时删除的元素。如果您捕获已删除的元素,您可以轻松地将它们添加回来:

let arr = [1,2,3,4,5,6];
// remove 1 element from index 1 ("2")
let removed = arr.splice(1, 1);
// add "2" back to position 1
arr.splice(1, 0, ...removed);

console.log(arr);

如果您无法访问 ES6 的扩展运算符,您可以使用 .shift()removed:

中获取第一个元素

let arr = [1,2,3,4,5,6];
// remove 1 element from index 1 ("2")
let removed = arr.splice(1, 1);
// add "2" back to position 1
arr.splice(1, 0, removed.shift());

console.log(arr);

单击 Delete random item 按钮将导致从 arr 数组中删除一个随机元素。删除的元素存储在 deleted 数组中。

单击 Undo deletion 按钮会将删除的元素移回 arr 数组的相同位置。

var arr = [5,1,2,6,4,8,0,7],
    stored = arr.slice(),
    deleted = [],
    btn = document.getElementById('deleteBtn'),
    undoBtn = document.getElementById('undoBtn');
    
    btn.addEventListener('click', function(){
      var randomElem = Math.floor(Math.random() * arr.length),
          deleteElem = arr.splice(randomElem, 1);
          deleted.push(...deleteElem);
          console.log(arr);
          console.log(deleteElem);
    });
    
    undoBtn.addEventListener('click', function(){
      if (arr.length >= 0 && arr.length < stored.length){
        var elem = deleted[deleted.length-1],
            index = stored.indexOf(elem);
            arr.splice(index, 0, elem);
            deleted.pop();
            console.log(arr);
      }
    });
    
console.log(arr);
<button id='deleteBtn'>Delete random item</button>
<button id='undoBtn'>Undo deletion</button>

我很想用某种可撤销的实用程序包装您的数组。例如:

function undoable(value) {
  let history = [value];

  return {
    value() {
      return history[history.length - 1];
    },
    update(func) {
      let copy = [...this.value()];
      func(copy);
      history.push(copy);
      return copy;
    },
    undo() {
      history.pop();
      return this.value();
    }
  }
}

您可以使用它来处理撤消行为。

let array = undoable([]);

array.update(arr => arr.push(2));
// [2]

array.update(arr => arr.push(3));
// [2, 3]

array.undo();
// [2]

如果在调用 update 期间将值视为不可变,则可以使它更安全、更通用。那时你不需要在将数组传递给 func 之前防御性地复制你的数组。但是,它会要求您使用 filterslice 之类的方法,而不是 splice.