javascript - 如何防止数组在 for 循环中更新?
问题描述
有一个包含许多其他数组的外部数组。我生成内部数组并将它们推送到外部数组。
for (i = 0; i < 12; i++) {
if (i == 0) {
var p = [];
for (n = 0; n < 4; n++) {
p.push(n);
}
} else {
s = i % (3);
var b = p[s+1];
p[s+1] = p[s];
p[s] = b;
}
console.log(p);
}
/*OUTPUT:
Array(4) [ 0, 1, 2, 3 ]
tsp.js:45:17
Array(4) [ 0, 2, 1, 3 ]
tsp.js:45:17
Array(4) [ 0, 2, 3, 1 ]
tsp.js:45:17
Array(4) [ 2, 0, 3, 1 ]
tsp.js:45:17
Array(4) [ 2, 3, 0, 1 ]
tsp.js:45:17
Array(4) [ 2, 3, 1, 0 ]
tsp.js:45:17
Array(4) [ 3, 2, 1, 0 ]
tsp.js:45:17
Array(4) [ 3, 1, 2, 0 ]
tsp.js:45:17
Array(4) [ 3, 1, 0, 2 ]
tsp.js:45:17
Array(4) [ 1, 3, 0, 2 ]
tsp.js:45:17
Array(4) [ 1, 0, 3, 2 ]
tsp.js:45:17
Array(4) [ 1, 0, 2, 3 ]
*/
此代码按预期输出许多不同的数组。但是这个输出一个包含相同数组的数组一遍又一遍:
o = [];
for (i = 0; i < 12; i++) {
if (i == 0) {
var p = [];
for (n = 0; n < 4; n++) {
p.push(n);
}
} else {
s = i % (3);
var b = p[s+1];
p[s+1] = p[s];
p[s] = b;
}
o.push(p);
}
console.log(o);
/*
OUTPUT:
(12) […]
0: Array(4) [ 1, 0, 2, … ]
1: Array(4) [ 1, 0, 2, … ]
2: Array(4) [ 1, 0, 2, … ]
3: Array(4) [ 1, 0, 2, … ]
4: Array(4) [ 1, 0, 2, … ]
5: Array(4) [ 1, 0, 2, … ]
6: Array(4) [ 1, 0, 2, … ]
7: Array(4) [ 1, 0, 2, … ]
8: Array(4) [ 1, 0, 2, … ]
9: Array(4) [ 1, 0, 2, … ]
10: Array(4) [ 1, 0, 2, … ]
11: Array(4) [ 1, 0, 2, … ]
length: 12
<prototype>: Array []
tsp.js:47:13
*/
我预计第二个代码会输出包装在一个数组中的 for 循环中的所有不同数组,但事实并非如此。
解决方案
当你这样做时,o.push(p);
你正在将引用推p
送到你的数组中。这意味着在您修改 中的元素时p
,在循环的每次迭代中,引用处的元素都会更改,从而更改数组中的o
数组。
p
因此,在将数组推入数组之前,您需要对数组进行唯一引用o
。一种方法是使用.slice()
像这样复制您的数组:
var o = [];
for (var i = 0; i < 12; i++) {
if (i == 0) {
var p = [];
for (var n = 0; n < 4; n++) {
p.push(n);
}
} else {
var s = i % (3);
var b = p[s + 1];
p[s + 1] = p[s];
p[s] = b;
}
o.push(p.slice()); // copy the elements in p to a new array, such that the array is now it's own unique reference in memory
}
console.log(o);
推荐阅读
- python - 为什么我得到 plotly express 属性错误?(AttributeError: 'Figure' 对象没有属性 'add_hline'
- azure - Azure 函数应用和 Web 套接字
- python - Apache Spark regexp_replace,将“\n”替换为实际表示?
- authentication - 即使在重定向之后也为loggedIn返回false
- php - 使用两个不同的表比较并插入日期和日历周
- javascript - jquery ajax 到 vanilla javascript(普通 javascript)代码转换请求
- asp.net-core - 如何使用基于策略的授权将所需的声明附加到令牌?
- flutter - 飞镖 | 将秒转换为 DateTime 而不计算
- google-cloud-platform - 如何使用 Google Ads API 更改我的应用程序设置以使刷新令牌不会过期?
- linux - 如何在 Linux 中通过 USB 使用 libcoap 进行通信?