对于项目,我需要导入Excel文件,将数据更改为JSON,并以不同的方式重新格式化,以便我的应用程序可读。一步是将Excel的一行拆分为两个不同的数组,这些数组必须单独更改。
但无论我做错了什么 - 对其中一个数组的任何更改不仅会相应地更改另一个数组,还会更改我的原始数据。
let data = [{
value1: 1,
value2: 2
}, {
value1: 3,
value2: 4
}]
let temp1 = [];
let temp2 = [];
for (let x of data) {
temp1.push(x); //pushing x in array 1
temp2.push(x); //pushing x as well in array 2
}
for (let x of temp1) {
x.type = 'typeA'
}
for (let x of temp2) {
x.type = 'typeB'
}
console.log(JSON.stringify(data));
console.log(JSON.stringify(temp1));
console.log(JSON.stringify(temp2));
//all three give the same result.

有人知道我的代码出错了吗?
答案 0 :(得分:3)
Javascript数组是基于引用的 - 因此您可以将其视为包含对相同值的引用的数组1和数组2。更改一个数组中的值将在另一个数组中更改它,因为它们无论如何都是相同的基础。
您真正需要的是如何深度克隆值。这是一个如何解决这个限制的例子。
let data = [{
value1: 1,
value2: 2
}, {
value1: 3,
value2: 4
}]
let temp1 = [];
for (let x of data) {
temp1.push(x); //pushing x in array 1
}
// This is one of the "workaround ways" of constructing
// an array of fresh values (otherwise known as deep cloning).
// this doesn't work in cases where you might have cyclic javascript
// objects or functions, but works if you're dealing with JSON values.
let temp2 = JSON.parse(JSON.stringify(temp1));
for (let x of temp1) {
x.type = 'typeA'
}
for (let x of temp2) {
x.type = 'typeB'
}
console.log(JSON.stringify(data));
console.log(JSON.stringify(temp1));
console.log(JSON.stringify(temp2));
//all three give the same result.

由于您实际上知道您的数据是对象列表,因此可以使用。在实践中,你可能想要使用更健壮的东西...比如lodash的cloneDeep:https://lodash.com/docs/4.17.4#cloneDeep
答案 1 :(得分:1)
数据是此处定义的唯一对象,您只是在进行引用并将数据推送到其他数组,
看看这些片段是如何运作的
var x = {};
var y = x;
y.age = 10;
console.log("x is :",x);
//{age:10;}
var a = [];
var b = a;
b.push(10);
console.log("a is :",a);
//[10]
答案 2 :(得分:1)
在您的问题中,您looping the data objects
并将其每个值分配给临时值,因此memory location
中的same as of data
将是JSON.parse(JSON.stringify(data))
。
因此,让for (let x of JSON.parse(JSON.stringify(data))) {
temp1.push(x); //pushing x in array 1
temp2.push(x); //pushing x as well in array 2
}
更改内存位置并将其循环,
更改,
let data = [{
value1: 1,
value2: 2
}, {
value1: 3,
value2: 4
}]
let temp1 = [];
let temp2 = [];
for (let x of JSON.parse(JSON.stringify(data))) {
temp1.push(x); //pushing x in array 1
temp2.push(x); //pushing x as well in array 2
}
temp1 = JSON.parse(JSON.stringify(temp1))
for (let x of temp1) {
x.type = 'typeA'
}
temp2 = JSON.parse(JSON.stringify(temp2))
for (let y of temp2) {
y.type = 'typeB'
}
console.log(JSON.stringify(data));
console.log(JSON.stringify(temp1));
console.log(JSON.stringify(temp2));
//all three give the same result.
# Libraries: stringr to extract the years and months,
# dplyr and tidyr for pipe operations
library(stringr)
library(dplyr)
library(tidyr)
df = read.table(text=tab, header=TRUE)
df = df %>%
mutate(
year = as.numeric(str_sub(YearMonth, 1, 4)),
month = as.numeric(str_sub(YearMonth, 5, 6))
) %>%
arrange(Client_ID, year, month) %>%
group_by(Client_ID) %>%
mutate(decline = c(FALSE, diff(Amount) < 0),
# Look at 2 upcoming rows and see if there was a decline in
# both of them
decline3 = (lead(decline, 1, default=FALSE) & lead(decline, 2, default=FALSE)))
请运行以上代码段
答案 3 :(得分:1)
data
,temp1
和temp2
确实是三个不同的数组,但temp1
和temp2
中的项只是对{ data
数组中的项目,因此它们都只是引用相同的对象。因此,更改一个数组中的对象将影响其他数组。
您可以做的不是运行temp1.push(x)
和temp2.push(x)
,而是push
代替x
对象的副本。这可以这样做:
temp1.push(Object.assign({}, x));
temp2.push(Object.assign({}, x));
这样,三个数组中包含的项目将是唯一对象,而不仅仅是对相同对象的引用。