我有这种形式的数据(简化,但假设Admin和Mining之间有20列):
Date,Series,Admin,Mining,CPI
1990,Ordinary Time Earnings,20,30,96
1991,Ordinary Time Earnings,22,33,100
1990,Total Earnings,25,38,96
1991,Total Earnings,29,43,100
我把它分成两个这样的系列:
d3.csv("avgearnings_v1_1.csv", function(error, data) {
if (error) throw error;
OrdinaryTimeEarnings = data
.filter(function(d) {
if(d.Series == 'Ordinary Time Earnings')
return d;
});
TotalEarnings = data
.filter(function(d) {
if(d.Series == "Total Earnings")
return d;
});
并且可以在没有任何问题的情况下显示在图表上。我接下来要做的是创建另外两个系列:
OrdinaryTimeEarningsReal = OrdinaryTimeEarnings;
TotalEarningsReal = TotalEarnings;
然后重新计算这些新系列。基本上是:
我的代码非常糟糕,但我可以使用这个来获取正确的值:
OrdinaryTimeEarningsReal
.forEach(function (z,i) {
var CPI = z["CPI"];
d3.map(z, function(b) {return b;})
.forEach(function (c) {
if(c !== "Date" && c !== "Series" && c !== "CPI" )
OrdinaryTimeEarningsReal[i][c] = ((z[c])/(CPI))*100;
});
});
但是,当我这样做时,它也会以某种方式更新原始的OrdinaryTimeEarnings系列,使它们彼此相等,而且OrdinaryTimeEarnings中的原始数据也会丢失。
我不确定我是否使用裸对象(在其中迭代,eek!)或上面的代码实际上是在更改原始数据中的值对象(以及我之后创建的所有4个系列都只是对它的引用)。
无论哪种方式,我都无法解决这个问题!我尝试了几种不同的语法形式,但无法解决问题。非常感谢帮助实现这一目标。
答案 0 :(得分:2)
如果您确实使用此代码“复制”数组:
OrdinaryTimeEarningsReal = OrdinaryTimeEarnings;
TotalEarningsReal = TotalEarnings;
然后你提到它是正确的,当你说他们引用同一个对象时。在JavaScript中,数组是可变的,使用上面的代码,您只需创建2个新变量,并引用内存中的现有数组。
要深度克隆对象数组,请使用以下方法:
OrdinaryTimeEarningsReal = JSON.parse(JSON.stringify(OrdinaryTimeEarnings));
TotalEarningsReal = JSON.parse(JSON.stringify(TotalEarnings));
这将创建数组的副本并将它们分配给新变量,这样当您编辑它们时,初始数组将不受影响。
现在,关于你的代码,它有点太复杂了。如果我理解你想要实现什么,你可以按如下方式简化它:
OrdinaryTimeEarningsReal
.forEach(function (z,i) {
for (var c in z) {
if (z.hasOwnProperty(c) && c !== "Date" && c !== "Series" && c !== "CPI" )
z[c] = z[c] / z.CPI * 100;
});
});
祝你好运!
答案 1 :(得分:1)
如果我理解正确:
data.forEach(function(d) {
for (var key in d) {
if (key !== 'Date' && key !== 'Series' && key !== 'CPI') {
d['new' + key] = (d[key] / d.CPI) * 100;
}
}
})
console.log(data)
我已将new
添加到新属性中,因此新的admin
值为newAdmin