Javascript 创建具有多样性的CSV&;大数据
我知道创建CSV文件的过程,因此我的问题更具体到我拥有的数据。我有一些录音机,每个都有一些数据。每个数据由值和时间戳组成。录音机是这样的:Javascript 创建具有多样性的CSV&;大数据,javascript,csv,lodash,Javascript,Csv,Lodash,我知道创建CSV文件的过程,因此我的问题更具体到我拥有的数据。我有一些录音机,每个都有一些数据。每个数据由值和时间戳组成。录音机是这样的: 'recorder_name': { samples: [{v: 19, t: new Date()}] } Date recorder_a recorder_b 2015-02-03 10 11 2015-02-04 15 - 问题在于并非所有记录器都具
'recorder_name': {
samples: [{v: 19, t: new Date()}]
}
Date recorder_a recorder_b
2015-02-03 10 11
2015-02-04 15 -
问题在于并非所有记录器都具有所有时间戳的值,并且它们的数据量也不相同。我开始玩lodash
,但它真的很慢。到目前为止,我掌握的情况如下:
function createCSVRows(data) {
const timestamps = [];
const csvRows = [];
//data contains all recorders
_.forEach(data, ({samples}) => {
_.forEach(samples, s => {
const timestamp = moment(s.t).utc();
timestamps.push(timestamp.format('YYYY-MM-DD HH:mm:ss'));
});
});
_(timestamps)
.uniq()
.sortBy(t => moment(t).utc())
.forEach(t => {
const csvRow = [t];
_.forEach(data, ({samples}) => {
const value = _.find(samples, s => moment(s.t).utc().format('YYYY-MM-DD HH:mm:ss') === t);
if(!value) {
csvRow.push('');
} else {
csvRow.push(value.v);
}
});
csvRows.push(csvRow);
})
.value();
return csvRows;
}
_.forEach(data, ({samples}) => {
_.forEach(samples, s => {
const timestamp = moment(s.t).utc().format('YYYY-MM-DD HH:mm:ss');
if(!timestamps[timestamp]) {
timestamps[timestamp] = [];
}
_.forEach(timestamps, (v, t) => {
if(t === timestamp) {
v.push(s.v);
} else {
v.push('');
}
});
});
});
因此,我尝试获取所有可用的时间戳,然后只保留唯一的时间戳。问题是如何获得每个时间戳的值。find
功能需要很多时间,因为每个记录器平均有500-600个数据点。我从未见过函数执行到最后,因为浏览器选项卡在短时间后消失
谢谢
编辑:根据@charlietfl的评论,我还尝试了以下方法:
function createCSVRows(data) {
const timestamps = [];
const csvRows = [];
//data contains all recorders
_.forEach(data, ({samples}) => {
_.forEach(samples, s => {
const timestamp = moment(s.t).utc();
timestamps.push(timestamp.format('YYYY-MM-DD HH:mm:ss'));
});
});
_(timestamps)
.uniq()
.sortBy(t => moment(t).utc())
.forEach(t => {
const csvRow = [t];
_.forEach(data, ({samples}) => {
const value = _.find(samples, s => moment(s.t).utc().format('YYYY-MM-DD HH:mm:ss') === t);
if(!value) {
csvRow.push('');
} else {
csvRow.push(value.v);
}
});
csvRows.push(csvRow);
})
.value();
return csvRows;
}
_.forEach(data, ({samples}) => {
_.forEach(samples, s => {
const timestamp = moment(s.t).utc().format('YYYY-MM-DD HH:mm:ss');
if(!timestamps[timestamp]) {
timestamps[timestamp] = [];
}
_.forEach(timestamps, (v, t) => {
if(t === timestamp) {
v.push(s.v);
} else {
v.push('');
}
});
});
});
问题是我必须循环时间戳,因为我必须用空值填充所有其他时间戳。这个标签还没用完。有什么想法吗
编辑2:
样本数据:
{
'recorder_a': {
samples: [{t: new Date(2015,02,03), v: 10}, {t: new Date(2015,02,04), v: 15}]
},
'recorder_b': {
samples: [{t: new Date(2015,02,03), v: 11}]
}
}
预期的CSV应该如下所示:
'recorder_name': {
samples: [{v: 19, t: new Date()}]
}
Date recorder_a recorder_b
2015-02-03 10 11
2015-02-04 15 -
我的意思是,如果记录器没有时间戳的值,那么我必须显示一个空shell。这里有一种方法应该可以工作。使用对象而不是数组来减少循环中大量的数组搜索
// object to store dates as keys
var dates = {} // {'2015-12-22':{recorder_a:4, recorder_c:7}}
// array of recorder names
var recorders = Object.keys(data);
// populate dates object with known recorders per date
recorders.forEach(function(recorder) {
data[recorder].samples.forEach(function(sample) {
var dateStr = getDateString(sample.t)
if (!dates[dateStr]) {
dates[dateStr] = {}
}
dates[dateStr][recorder] = sample.v
});
});
// array of date keys sorted
var datesArr = Object.keys(dates).sort(function(a, b) {
return new Date(a) - new Date(b);
});
var headings= ['Date'].concat(recorders);
// now fill in missing recorders on each date
var res = [csvRow(headings)];
datesArr.forEach(function(date) {
var row = [date],
rowData = dates[date];
recorders.forEach(function(recorder) {
var value = rowData.hasOwnProperty(recorder) ? rowData[recorder] : '';
row.push(value)
});
res.push(csvRow(row))
});
// final csv result string
var csv = res.join('')
// row csv helper
function csvRow(arr){
return '"'+ arr.join('","')+'"\n'
}
// helper
function getDateString(date) {
return date.toISOString().slice(0, 10);
}
更有效地创建时间戳为键的对象。迭代一次并检查键是否存在。然后迭代对象以映射回数组。将删除
find()
正在执行的重复数组搜索doing@charlietfl你的意思是不在数组中添加时间戳?你能提供一个小例子吗?是的。。从一开始。若对象不存在,则向其添加时间戳,并将值指定为行。忽略,如果它已经存在,我看到,将测试它,并让你知道由于某种原因,日期排序是不正确的工作各地。必须返回新日期(a)-新日期(b)
是的…我把它作为一个快速的概念。字符串不是最好的