2017-04-04 115 views
0

對於一個項目,我需要導入一個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.

有誰知道我的代碼在哪裏呢?

回答

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

數據是在這裏定義,你只是做參考和數據推送到其他陣列的唯一對象,

看看這些片段是如何工作太

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]

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.

請運行上面的代碼中

+0

@Torf,但你不需要你的原始數組被改變嗎?,你的原始數組不需要'type'值。檢查我的答案。 – Sravan

+0

你需要你的原始數組來獲得類型值? – Sravan

+0

沒錯。我的原始數據不需要任何更改(在這一點上 - 之前已更改)。這些類型僅用於派生數組。 – Torf

1

這是事實,datatemp1temp2三種不同的陣列,但在temp1temp2的項目是給data數組中的項目只是引用,所以他們都只是指的同一對象。因此,更改一個數組中的對象將影響其他數組。

您可以做的不是運行temp1.push(x)temp2.push(x),而是push副本,而不是x對象。可以這樣做,像這樣:

temp1.push(Object.assign({}, x)); 
temp2.push(Object.assign({}, x)); 

這種方式,包含在你的三個陣列中的項目將是唯一的目標,而不僅僅是同一對象的引用。

相關問題