我使用以下函数来解析csv文件。
export default function readCsv (csv, reviver) {
reviver = reviver || function(r, c, v) {
return v;
};
let chars = csv.split(''),
c = 0,
cc = chars.length,
start, end, table = [],
row;
while (c < cc) {
table.push(row = []);
while (c < cc && '\r' !== chars[c] && '\n' !== chars[c]) {
start = end = c;
if ('"' === chars[c]) {
start = end = ++c;
while (c < cc) {
if ('"' === chars[c]) {
if ('"' !== chars[c + 1]) {
break;
} else {
chars[++c] = '';
} // unescape ""
}
end = ++c;
}
if ('"' === chars[c]) {
++c;
}
while (c < cc && '\r' !== chars[c] && '\n' !== chars[c] && ',' !== chars[c]) {
++c;
}
} else {
while (c < cc && '\r' !== chars[c] && '\n' !== chars[c] && ',' !== chars[c]) {
end = ++c;
}
}
row.push(reviver(table.length - 1, row.length, chars.slice(start, end).join('')));
if (',' === chars[c]) {
++c;
}
}
if ('\r' === chars[c]) {
++c;
}
if ('\n' === chars[c]) {
++c;
}
}
return table;
}
json看起来像这样:
我希望json看起来如下:
[
doc_id: "16278",
framework_id: "8078",
...
],
[
doc_id: "16261",
framework_id: "880",
...
],
基本上,不是将第一行的内容作为json中的第一个值,而是将第一行转换为键,将其余行转换为值。
答案 0 :(得分:3)
对数据进行后期处理以将其映射到所需格式是相对简单的,即给定CSV变量data
中的CSV读取器的输出:
data = data.slice(1).map(function(row) {
return row.reduce(function(obj, value, index) {
var key = data[0][index]; // extract from first original row
obj[key] = value;
return obj;
}, {});
});
即。迭代所有行(跳过第1行),根据第0行中的键和当前值创建对象。
请注意,这将使用长格式的原始密钥。您可能希望更改第一行中的值以使它们首先更加标准化,例如:
data[0] = data[0].map(function(key) {
key = key.replace(/[^\w\d\s]/g, ''); // strip non-alphanum or space
return key.replace(/\s/g, '_').toLowerCase();
});
答案 1 :(得分:0)
这是一种有效的方法:
function csvToKeyedArray(csv) {
var data = [];
var keys = csv[0];
var datum, entry, index;
for (index in keys) {
keys[index] = keys[index]
.replace(/[^\w ]+/g, '') // remove extraneous characters like '?'
.replace(/ /g, '_') // replace spaces with _
.toLowerCase();
}
for (entry = 1; entry < csv.length; entry++) {
// initialize an object for each row and add it to the `data` array
data[entry - 1] = datum = {};
for (index in keys) {
// convert rows to objects
datum[keys[index]] = csv[entry][index];
}
}
return data;
}
然后根据您的规范填充 data
。
如果您的CSV文件包含10000行,则优于使用.map()
,因为每次迭代的函数调用导致的上下文切换开销将导致其明显变慢。
但是,如果您的CSV文件预计只有几百或几千行,那么使用.map()
可能会更好,以提高可读性和可维护性。
答案 2 :(得分:-1)
试试这个:
const csvData = `
id,first_name,last_name,email,gender,ip_address
1,Jami,Dumingos,jdumingos0@opensource.org,Female,209.112.103.56
2,Brenda,Harbach,bharbach1@addtoany.com,Female,160.201.233.94
3,Gail,Rowbrey,growbrey2@sakura.ne.jp,Female,160.199.58.40
4,Ludvig,Coil,lcoil3@fotki.com,Male,158.37.136.163
5,Lurlene,Conochie,lconochie4@skyrock.com,Female,145.147.12.44
6,Aldous,Farrey,afarrey5@cargocollective.com,Male,44.148.54.88
7,Skipp,Sket,ssket6@discovery.com,Male,81.190.215.227
8,Greg,Wakefield,gwakefield7@yahoo.com,Male,105.157.167.96
9,Westley,Purton,wpurton8@mapquest.com,Male,169.67.113.22
10,Dill,Avraam,davraam9@google.de,Male,223.60.54.101`;
function readCsv(csv, splitMark = ',') {
const lines = csv.split('\n');
const keys = lines[0].split(splitMark); // first line as heading
const rows = lines.slice(1, lines.length - 1);
return rows.map(row => row
.split(splitMark)
.reduce((map, col, index) => {
map[keys[index]] = col;
return map;
}, { }));
}
readCsv(csvData);