我有一个类似于以下架构的JSON响应...
{
"resultCode": 200,
"message": "Success",
"generated": "2018-11-14T18:42:02",
"expires": "2018-11-14T18:50:00",
"data": {
"generationByFuel": [
{
"date": "2018-11-14T00:00:00",
"period": 37,
"generation": [
{
"fuel": "Hydro",
"generation": 1011.298,
"capacity": 2000
},
{
"fuel": "Wind",
"generation": 2544.788,
"capacity": 3500
}
]
},
{
"date": "2018-11-14T00:00:00",
"period": 36,
"generation": [
{
"fuel": "Hydro",
"generation": 1100,
"capacity": 2000
},
{
"fuel": "Wind",
"generation": 2500,
"capacity": 3500
}
]
}
]
}
}
由此,我需要提取多个数组,并将其插入googlesheet(“ shtGen”)中,并填充以下各列:
|日期|期间|燃油|世代|容量运行时|
我猜我需要做的是写输出(generationByFuel[i](generation[r]))
的东西,但我正在努力弄清楚该怎么做。
我尝试了许多选择,但以下是我认为自己走在正确轨道上的最后一次尝试。也就是说,该函数运行时不会返回错误,但不会在Google工作表中插入任何信息。当我使用调试器运行函数时,也会发生同样的事情。
// define output to paste into sheet
for (var i in genData) {
var iInput = [];
iInput.push(genData[i].date);
iInput.push(genData[i].period);
for (var r in fuelData) {
var rInput = [];
rInput.push(fuelData[r].fuel);
rInput.push(fuelData[r].capacity);
rInput.push(fuelData[r].generation);
rInput.push(now = new Date());
shtGen.appendRow(iInput + rInput);
}
}
这里的任何帮助或建议将不胜感激。预先感谢!
答案 0 :(得分:2)
此修改如何?我认为针对您的情况有几种解决方案。因此,请将此视为其中之一。
fuelData
。
iInput + rInput
成为字符串类型。这样,在appendRow()
处发生错误。
iInput.concat(rInput)
用于此。| Date | Period | Fuel | Generation | Capacity | Runtime |
,要求将值推入的顺序为
rInput.push(fuelData[r].fuel)
rInput.push(fuelData[r].generation)
rInput.push(fuelData[r].capacity)
在此经过修改的脚本中,obj
是您问题中的json对象。然后shtGen
假设工作表对象。
var obj = {### your json object ###};
var genData = obj.data.generationByFuel;
for (var i in genData) {
var iInput = [];
iInput.push(genData[i].date);
iInput.push(genData[i].period);
var fuelData = genData[i].generation; // Added
for (var r in fuelData) {
var rInput = [];
rInput.push(fuelData[r].fuel); // Modified
rInput.push(fuelData[r].generation); // Modified
rInput.push(fuelData[r].capacity); // Modified
rInput.push(new Date());
shtGen.appendRow(iInput.concat(rInput)); // Modified
}
}
我认为,当对象较大时,appendRow()
成为处理成本增加的原因。因此,我建议如下使用setValues()
将值放入电子表格。
var obj = {### your json object ###};
var res = [];
var genData = obj.data.generationByFuel;
for (var i in genData) {
var iInput = [];
iInput.push(genData[i].date);
iInput.push(genData[i].period);
var fuelData = genData[i].generation;
for (var r in fuelData) {
var rInput = [];
rInput.push(fuelData[r].fuel);
rInput.push(fuelData[r].generation);
rInput.push(fuelData[r].capacity);
rInput.push(new Date());
res.push(iInput.concat(rInput)); // Modified
}
}
shtGen.getRange(shtGen.getLastRow() + 1, 1, res.length, res[0].length).setValues(res); // Added
作为其他修改之一,您还可以使用以下脚本。该脚本的成本低于上述脚本的成本。
var obj = {### your json object ###};
var res = obj.data.generationByFuel.reduce(function(ar, e) {
return ar.concat(e.generation.map(function(f) {
return [e.date, e.period, f.fuel, f.generation, f.capacity, new Date()];
}));
}, []);
shtGen.getRange(shtGen.getLastRow() + 1, 1, res.length, res[0].length).setValues(res);
如果这不是您想要的,请告诉我。我想修改它。
答案 1 :(得分:1)
这是利用JSON.parse()
的另一种方法。
Reviver函数是JSON.parse()
的可选参数。这些功能的妙处在于,它们使用深度优先搜索为JSON对象树中的每个节点使用键/值对进行调用。
运行以下代码片段以了解其工作原理:
{{ dropzone.config(custom_init='dz2 = this;document.getElementById("uploadID").addEventListener("click", function handler(e) {dz2.processQueue();});',
custom_options='autoProcessQueue: false, addRemoveLinks: true, maxFiles: 2,DROPZONE_UPLOAD_ACTION:handle_upload2,') }}
由以上脚本生成的控制台日志“深度优先”遍历对象树;在打印父节点的值之前,它将向下钻取以打印出叶节点的值。例如:var jsonString = JSON.stringify({
"resultCode": 200,
"message": "Success",
"generated": "2018-11-14T18:42:02",
"expires": "2018-11-14T18:50:00",
"data": {
"generationByFuel": [
{
"date": "2018-11-14T00:00:00",
"period": 37,
"generation": [
{
"fuel": "Hydro",
"generation": 1011.298,
"capacity": 2000
},
{
"fuel": "Wind",
"generation": 2544.788,
"capacity": 3500
}
]
},
{
"date": "2018-11-14T00:00:00",
"period": 36,
"generation": [
{
"fuel": "Hydro",
"generation": 1100,
"capacity": 2000
},
{
"fuel": "Wind",
"generation": 2500,
"capacity": 3500
}
]
}
]
}
});
JSON.parse(jsonString, function(key, value) {
console.log("Key:%s, Value:%o", key, value);
return value;
});
在包含它的"fuel":"Hydro"
数组之前打印。
您可以利用它为电子表格生成必要的数据,如下所示:
"generation":[{...}, {...},..]
上面的代码段在reviver遍历JSON的对象树并填充2D values数组的过程中过滤出所需的数据。现在,您要做的就是使用值数组在工作表上调用var jsonString = JSON.stringify({
"resultCode": 200,
"message": "Success",
"generated": "2018-11-14T18:42:02",
"expires": "2018-11-14T18:50:00",
"data": {
"generationByFuel": [
{
"date": "2018-11-14T00:00:00",
"period": 37,
"generation": [
{
"fuel": "Hydro",
"generation": 1011.298,
"capacity": 2000
},
{
"fuel": "Wind",
"generation": 2544.788,
"capacity": 3500
}
]
},
{
"date": "2018-11-14T00:00:00",
"period": 36,
"generation": [
{
"fuel": "Hydro",
"generation": 1100,
"capacity": 2000
},
{
"fuel": "Wind",
"generation": 2500,
"capacity": 3500
}
]
}
]
}
});
var values = [];
var state = {};
JSON.parse(jsonString, function(key, value) {
switch(key) {
case "generation":
if (Array.isArray(value)) break;
case "date":
case "period":
case "fuel":
case "capacity":
state[key] = value;
break;
}
if (key === "capacity") {
values.push([
state.date,
state.period,
state.fuel,
state.generation,
state.capacity,
new Date()
]);
}
return value;
});
console.log(values);
。
答案 2 :(得分:0)
我认为您错过了var'r'for循环中的“ genData [i]”。试试这个。
for (var i in genData) {
var iInput = [];
iInput.push(genData[i].date);
iInput.push(genData[i].period);
for (var r in fuelData) {
var rInput = [];
rInput.push(genData[i].fuelData[r].fuel);
rInput.push(genData[i].fuelData[r].capacity);
rInput.push(genData[i].fuelData[r].generation);
rInput.push(now = new Date());
shtGen.appendRow(iInput + rInput);
}
}
这也可能是您将响应存储在模型类中的方式。