【问题标题】:A copy of an array changes the original array even with slice [duplicate]即使使用切片,数组的副本也会更改原始数组[重复]
【发布时间】:2021-11-18 00:13:44
【问题描述】:

我正在尝试创建一个数组的副本,以便在保存原始数组的同时对副本进行更改。我正在使用 slice 函数来复制数组,但由于某种原因它仍在更改两个数组。嵌入的代码将无法运行,因为我使用的是无法导入的自定义字体

let font;
let num1;

function preload() {
  font = loadFont("Pacifico-Regular.ttf")
}
function setup() {
  createCanvas(350, 350);
  num1 = new num("1", 350 / 2, 350 / 2, 200)
  num1.randomize(-5, 5)
  num1.show()
}
function draw() {}

class num {
  constructor(text, centerX, centerY, fontSize) {
    this.text = text;
    this.centerX = centerX;
    this.centerY = centerY;
    this.fontSize = fontSize;
    this.oldArray = font.textToPoints(this.text, this.centerX, this.centerY, this.fontSize);
    this.newArray = this.oldArray.slice(); //Here is where I make a copy of the Array
  }
  //Randomizes old array
  randomize(min, max) {
    for (let i = 0; i < this.oldArray.length; i++) {
      this.oldArray[i].x = this.oldArray[i].x + random(min, max);
      this.oldArray[i].y = this.oldArray[i].y + random(min, max);
    }
  }
  //Draws new array
  show() {
    beginShape()
    for (let i = 0; i < this.newArray.length; i++) {
      vertex(this.newArray[i].x, this.newArray[i].y)
    }
    endShape(CLOSE)
  }
  //Moves new array
  move(x, y) {
    for (let i = 0; i < this.newArray.length; i++) {
      this.newArray[i].x = this.newArray[i].x + x;
      this.newArray[i].y = this.newArray[i].y + y;
    }
  }
  //Returns old array
  return() {
    this.newArray = this.oldArray.slice();
  }
}
&lt;script src="https://cdn.jsdelivr.net/npm/p5@1.4.0/lib/p5.js"&gt;&lt;/script&gt;

【问题讨论】:

  • 拼接改变输入数组

标签: javascript p5.js mutability


【解决方案1】:

您不是在更改数组,而是在更改数组中的对象。你不想这样。

const myObj = {
  x:1,
  y:1
};

const myArray = [myObj];
const myNewArray = [...myArray];

myNewArray[0].x = 2;
console.log(myArray[0].x); // 2!!!!!

如果您正在更改数组中的一个对象并且您不希望它发生变异,那么请执行以下操作:

const myObj = {
  x:1,
  y:1
};

const myArray = [myObj];

// helper function that will perform a mutation at a given position
// and ignore all other positions
const mutateObjectAtPosition = (pos,mutation) => [...myArray].map((o,i) => i === pos ? mutation(o) : o)

// at position 0, return a **new object** with x set to 2
const myNewArray = mutateObjectAtPosition(0,(o) => ({...o,x:2}));

console.log(myNewArray !== myArray); // true, different references
console.log(myNewArray[0].x); // 2
console.log(myArray[0].x); // 1


【讨论】:

  • 谢谢,我没有意识到 splice 已被弃用。我将使用地图,这样我就可以复制数组并同时进行更改。
  • splice 没有被弃用,它只是用于不同的目的。
  • p5 文档说它已被弃用。 p5js.org/reference/#/p5/splice
  • @billyjean,奇怪,我说的是this splice
【解决方案2】:

新的数组复制方式如下:

const cloneSheepsES6 = [...sheeps];

但我认为您的问题可能与该行有关:

return() {
    this.newArray = this.oldArray.slice();
  }

您返回新数组但再次将其设置为旧数组的副本。 所以我认为只要简单地返回 newArray 你应该解决你的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-18
    • 2020-10-04
    • 2021-04-01
    • 1970-01-01
    • 2019-09-29
    • 1970-01-01
    • 2016-01-10
    相关资源
    最近更新 更多