我知道创建CSV文件的过程,所以我的问题更具体到我拥有的数据。我有一些录像机,每个都有一些数据。每个数据都包含值和时间戳。所以录音机看起来像这样:
'recorder_name': {
samples: [{v: 19, t: new Date()}]
}
问题是并非所有记录器都具有所有时间戳的值,并且它们没有相同数量的数据。我开始玩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;
}
所以,我尝试获取所有可用的时间戳,然后只保留唯一的时间戳。问题是如何获取每个时间戳的值。 find
函数需要花费很多时间,因为每个记录器平均有500-600个数据点。我从未见过函数执行到最后,因为浏览器选项卡会在很短的时间后死掉。
由于
编辑:根据@charlietfl的评论,我还尝试了以下内容:
_.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应如下所示:
Date recorder_a recorder_b
2015-02-03 10 11
2015-02-04 15 -
我的意思是,如果录音机没有时间戳的值,那么我必须显示一个空壳。
答案 0 :(得分:1)
这是一种应该有效的方法。使用对象而不是数组来减少循环中的大量数组搜索
// 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);
}
的 DEMO 强>