Javascript 使用lodash和reduce重塑JSON
我想从从URL下载的解析CSV文件中重塑JSON 我使用“csvtojson”模块解析CSV并创建一个需要重塑的JSON 下面是我的完整代码:Javascript 使用lodash和reduce重塑JSON,javascript,node.js,json,lodash,Javascript,Node.js,Json,Lodash,我想从从URL下载的解析CSV文件中重塑JSON 我使用“csvtojson”模块解析CSV并创建一个需要重塑的JSON 下面是我的完整代码: const _ = require('lodash') // to handle datetimes const moment = require('moment') // to convert csv to json const csv = require('csvtojson') // to save files to disk const fs
const _ = require('lodash')
// to handle datetimes
const moment = require('moment')
// to convert csv to json
const csv = require('csvtojson')
// to save files to disk
const fs = require('fs')
const fsPromises = fs.promises;
const path = require('path')
// to load data stream from url
const axios = require('axios')
// to schedule downloading
const schedule = require('node-schedule');
//let t = moment('2020-01-30 02:59:59+01')
// console.log(t.format())
// console.log(t.toDate())
const urlBaseFile = 'http://cemec.arpacampania.it/meteoambientecampania/php/downloadFileDati.php?path=/var/www/html/meteoambientecampania/prodotti/aria/arpac_dati_centraline'
const path_fileJSON = path.resolve(__dirname, '../data.json')
const path_fileCSV = path.resolve(__dirname, '../data.csv')
const downloadCSV = async (date) => {
const url = urlBaseFile + '_' +
(!date ? moment().format('YYYYMMDD') : date) + '.csv'
const writerCSV = fs.createWriteStream(path_fileCSV)
try {
let response = await axios.get(url, {
responseType: 'stream'
})
await response.data.pipe(writerCSV)
const json_from_csv = await response.data.pipe(csv())
const json_from_csv_filtered = json_from_csv.filter(d => d.descrizione == 'Portici Parco Reggia').map(d => {
return {
// convert to Date object UTC format
// moment(d.data_ora).format()
datetime: moment(d.data_ora).toISOString(),
[d.inquinante]: parseFloat(d.valore),
// pollutant: d.inquinante,
// value: parseFloat(d.valore), // convert to float
//unit: d.um
}
})
await fsPromises.writeFile(path_fileJSON, JSON.stringify(json_from_csv_filtered, null, 4))
const res = json_from_csv_filtered.reduce((acc, val) => {
const find = acc.find(el => el.date === val.datetime.substring(0, 10));
const {
datetime,
...obj
} = val;
if (find) {
find.values[0] = {
...find.values[0],
...obj
};
} else {
acc.push({
date: datetime.substring(0, 10),
values: [{
t: datetime,
...obj
}]
});
}
return acc;
}, []);
console.log(JSON.stringify(res, null, 4))
} catch (err) {
console.error(err)
}
}
downloadCSV()
我获得:
[
{
"date": "2020-06-28",
"values": [
{
"t": "2020-06-28T23:59:59.000Z",
"Benzene": 0.5,
"NO2": 44.7,
"O3": 23.2
}
]
},
{
"date": "2020-06-29",
"values": [
{
"t": "2020-06-29T00:59:59.000Z",
"Benzene": 4.3,
"NO2": 11.5,
"O3": 67.8
}
]
}
]
整个JSON模式是正确的,但我应该获得日期2020-06-29的附加项,而只返回1项
怎么了
谢谢。从和您的评论中,我假设您的响应数据如下所示。据我从您的评论中了解,您希望按日期从datetime
对值进行分组,然后根据不同的小时将多个对象放入组的values
数组中。我用groupBy
函数进行了尝试。为了解决这个问题,我采用了两种方法
datetime
let数据=[
{
“日期时间”:“2020-06-29T23:59:59.000Z”,
“苯”:1.9
},
{
“日期时间”:“2020-06-30T00:59:59.000Z”,
“苯”:0.6
},
{
“日期时间”:“2020-06-30T01:59:59.000Z”,
“苯”:5.7
},
{
“日期时间”:“2020-06-30T02:59:59.000Z”,
“苯”:5.5
},
{
“日期时间”:“2020-06-30T03:59:59.000Z”,
“苯”:5.2
},
{
“日期时间”:“2020-06-30T04:59:59.000Z”,
“苯”:1
},
{
“日期时间”:“2020-06-30T05:59:59.000Z”,
“苯”:2.1
},
{
“日期时间”:“2020-06-30T06:59:59.000Z”,
“苯”:4.2
},
{
“日期时间”:“2020-06-30T07:59:59.000Z”,
“苯”:3.4
},
{
“日期时间”:“2020-06-30T00:59:59.000Z”,
“NO2”:16.3
},
{
“日期时间”:“2020-06-30T01:59:59.000Z”,
“NO2”:12.6
},
{
“日期时间”:“2020-06-30T02:59:59.000Z”,
“NO2”:11.7
},
{
“日期时间”:“2020-06-30T03:59:59.000Z”,
“NO2”:35.5
},
{
“日期时间”:“2020-06-30T04:59:59.000Z”,
“NO2”:44.6
},
{
“日期时间”:“2020-06-30T05:59:59.000Z”,
“NO2”:19.9
},
{
“日期时间”:“2020-06-30T06:59:59.000Z”,
“NO2”:11.2
},
{
“日期时间”:“2020-06-30T07:59:59.000Z”,
“NO2”:8.2
},
{
“日期时间”:“2020-06-29T23:59:59.000Z”,
“O3”:25.6
},
{
“日期时间”:“2020-06-30T01:59:59.000Z”,
“O3”:31.7
},
{
“日期时间”:“2020-06-30T02:59:59.000Z”,
“O3”:35.1
},
{
“日期时间”:“2020-06-30T03:59:59.000Z”,
“O3”:11.4
},
{
“日期时间”:“2020-06-30T04:59:59.000Z”,
“O3”:4.9
},
{
“日期时间”:“2020-06-30T05:59:59.000Z”,
“O3”:32.8
},
{
“日期时间”:“2020-06-30T06:59:59.000Z”,
“O3”:46.4
},
{
“日期时间”:“2020-06-30T07:59:59.000Z”,
“O3”:55.6
}
];
const-groupsByDate=u.groupBy(数据,val=>val.datetime.split('T')[0]);
const res=Object.entries(groupsByDate.map)([date,vals])=>{
const groupsByTime=u.groupBy(vals,val=>val.datetime.split('T')[1]);
返回{
日期,
值:Object.values(groupsByTime.map(arr=>Object.assign({},…arr))
};
});
log(JSON.stringify(res,null,2))代码>
只要浏览一下脚本,find.values[0]
将只从values数组中获取第一个元素。也许这就是问题所在?不,这不是问题所在。使用“find.values”不会更改结果。与前面一样,预期的结果是将每个组对象值组合到单个元素values
array中。是否希望组的所有对象值都位于一个数组中(多个对象不是单个对象)?如果是这样,则应将obj
值推送到find.values
数组中,而不是将obj
分解为find.values[0]
。如果我错了,请用适当的输入数据和输出数据来澄清您的问题。@ParthoShuvo,预期输出应该是:[{“日期”:“2020-06-30”,“值”:[{“t”:“2020-06-30T00:59:59.000Z”,“苯”:5.5,“NO2”:11.7,“O3”:35.1},{“t”:“2020-06-30T01:59:59.000Z”,“苯”:5.2,“NO2”:15.7,“O3”:55.7}]}]在同一日期内有多个对象,但每小时一个,收集所有传感器读数。相反,我只得到最后一个小时的阅读。@ParthoShuvo,在这篇新的文章中,我希望澄清这个问题。我能够找到一个解决方案,但我最不喜欢它。如果你能建议一个更好的方法。。。谢谢