将 CSV 行转换为 Javascript 个对象
convert CSV lines into Javascript objects
我有一个简单的 csv 文件
people.csv:
fname, lname, uid, phone, address
John, Doe, 1, 444-555-6666, 34 dead rd
Jane, Doe, 2, 555-444-7777, 24 dead rd
Jimmy, James, 3, 111-222-3333, 60 alive way
我想做的是获取 CSV 的每一行,将其转换为 JavaScript 对象,将它们存储到数组中,然后将数组转换为 JSON 对象。
server.js:
var http = require('http');
var url = require('url');
var fs = require('fs');
var args = process.argv;
var type = args[2] || 'text';
var arr = [];
var bufferString;
function csvHandler(req, res){
fs.readFile('people.csv',function (err,data) {
if (err) {
return console.log(err);
}
//Convert and store csv information into a buffer.
bufferString = data.toString();
//Store information for each individual person in an array index. Split it by every newline in the csv file.
arr = bufferString.split('\n');
console.log(arr);
for (i = 0; i < arr.length; i++) {
JSON.stringify(arr[i]);
}
JSON.parse(arr);
res.send(arr);
});
}
//More code ommitted
我的问题是,当我在 bufferString 上调用 .split('\n') 方法时,我是否真的将 CSV 行转换为 Javascript 对象,或者是否有其他方法?
通过这样做:
arr = bufferString.split('\n');
您将拥有一个包含所有行的数组作为字符串
["fname, lname, uid, phone, address","John, Doe, 1, 444-555-6666, 34 dead rd",...]
您必须使用 .split(',')
用逗号再次分隔它,然后将 headers 分开并将其推入 Javascript Object:
var jsonObj = [];
var headers = arr[0].split(',');
for(var i = 1; i < arr.length; i++) {
var data = arr[i].split(',');
var obj = {};
for(var j = 0; j < data.length; j++) {
obj[headers[j].trim()] = data[j].trim();
}
jsonObj.push(obj);
}
JSON.stringify(jsonObj);
那么你会得到这样的object:
[{"fname":"John",
"lname":"Doe",
"uid":"1",
"phone":"444-555-6666",
"address":"34 dead rd"
}, ... }]
看到这个FIDDLE
您可以尝试使用 MVC Razor,
<script type="text/javascript">
MyNamespace.myConfig = @Html.Raw(Json.Encode(new MyConfigObject()));
</script>
Json.Encode会将初始化对象序列化为JSON格式。然后 Html.Raw 将阻止它将引号编码为 ".
此处完整example
您可以使用 lodash(或下划线)来帮助解决这个问题。
var objects = _.map(arr, function(item){return item.split(',');});
var headers = objects[0];
objects.splice(0, 1); // remove the header line
populatedObject = [];
objects.forEach(function(item){
var obj = _.zipObject(headers, item);
populatedObject.push(obj);
});
.zipObject 方法会将每个 header 与 items 数组中的每个值匹配并生成一个 object。
使用ES6/ES7和一些函数式编程指南:
- 所有变量都是
const
(不变性)
- 使用
map
/reduce
代替while
/for
- 所有功能都是箭头
- 无依赖关系
// Split data into lines and separate headers from actual data
// using Array spread operator
const [headerLine, ...lines] = data.split('\n');
// Split headers line into an array
// `valueSeparator` may come from some kind of argument
// You may want to transform header strings into something more
// usable, like `camelCase` or `lowercase-space-to-dash`
const valueSeparator = '\t';
const headers = headerLine.split(valueSeparator);
// Create objects from parsing lines
// There will be as much objects as lines
const objects = lines
.map( (line, index) =>
line
// Split line with value separators
.split(valueSeparator)
// Reduce values array into an object like: { [header]: value }
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
.reduce(
// Reducer callback
(object, value, index) => ({
...object,
[ headers[index] ]: value,
}),
// Initial value (empty JS object)
{}
)
);
console.log("Objects:", objects);
对于使用 ,
作为分隔符和引号字符串值的 CSV 文件,您可以使用此版本:
// Split data into lines and separate headers from actual data
// using Array spread operator
const [headerLine, ...lines] = data.split('\n');
// Use common line separator, which parses each line as the contents of a JSON array
const parseLine = (line) => JSON.parse(`[${line}]`);
// Split headers line into an array
const headers = parseLine(headerLine);
// Create objects from parsing lines
// There will be as much objects as lines
const objects = lines
.map( (line, index) =>
// Split line with JSON
parseLine(line)
// Reduce values array into an object like: { [header]: value }
.reduce(
(object, value, index) => ({
...object,
[ headers[index] ]: value,
}),
{}
)
);
return objects;
注意:对于大文件,最好使用流、生成器、迭代器等
如果您已经有一个数组并希望 csv header(第一行)成为 object 的 属性。
,那么这是一个解决方案
const csvArrayToObj = (csvData) => {
return csvData
.map((csvLine, csvIndex) => {
if (csvIndex === 0 || !csvLine.length) return null; // skip header and empty lines
return csvLine.reduce((a, v, i) => ({ ...a, [csvData[0][i]]: v }), {});
})
.filter((filter) => !!filter); //filter empty lines
};
const csvArray = [
['name', 'age'],
['John Doe', 20],
['Jane Doe', 30],
];
csvArrayToObj(csvArray);
// output
[
{
"name": "John Doe",
"age": 20
},
{
"name": "Jane Doe",
"age": 30
}
]
我有一个简单的 csv 文件
people.csv:
fname, lname, uid, phone, address
John, Doe, 1, 444-555-6666, 34 dead rd
Jane, Doe, 2, 555-444-7777, 24 dead rd
Jimmy, James, 3, 111-222-3333, 60 alive way
我想做的是获取 CSV 的每一行,将其转换为 JavaScript 对象,将它们存储到数组中,然后将数组转换为 JSON 对象。
server.js:
var http = require('http');
var url = require('url');
var fs = require('fs');
var args = process.argv;
var type = args[2] || 'text';
var arr = [];
var bufferString;
function csvHandler(req, res){
fs.readFile('people.csv',function (err,data) {
if (err) {
return console.log(err);
}
//Convert and store csv information into a buffer.
bufferString = data.toString();
//Store information for each individual person in an array index. Split it by every newline in the csv file.
arr = bufferString.split('\n');
console.log(arr);
for (i = 0; i < arr.length; i++) {
JSON.stringify(arr[i]);
}
JSON.parse(arr);
res.send(arr);
});
}
//More code ommitted
我的问题是,当我在 bufferString 上调用 .split('\n') 方法时,我是否真的将 CSV 行转换为 Javascript 对象,或者是否有其他方法?
通过这样做:
arr = bufferString.split('\n');
您将拥有一个包含所有行的数组作为字符串
["fname, lname, uid, phone, address","John, Doe, 1, 444-555-6666, 34 dead rd",...]
您必须使用 .split(',')
用逗号再次分隔它,然后将 headers 分开并将其推入 Javascript Object:
var jsonObj = [];
var headers = arr[0].split(',');
for(var i = 1; i < arr.length; i++) {
var data = arr[i].split(',');
var obj = {};
for(var j = 0; j < data.length; j++) {
obj[headers[j].trim()] = data[j].trim();
}
jsonObj.push(obj);
}
JSON.stringify(jsonObj);
那么你会得到这样的object:
[{"fname":"John",
"lname":"Doe",
"uid":"1",
"phone":"444-555-6666",
"address":"34 dead rd"
}, ... }]
看到这个FIDDLE
您可以尝试使用 MVC Razor,
<script type="text/javascript">
MyNamespace.myConfig = @Html.Raw(Json.Encode(new MyConfigObject()));
</script>
Json.Encode会将初始化对象序列化为JSON格式。然后 Html.Raw 将阻止它将引号编码为 ".
此处完整example
您可以使用 lodash(或下划线)来帮助解决这个问题。
var objects = _.map(arr, function(item){return item.split(',');});
var headers = objects[0];
objects.splice(0, 1); // remove the header line
populatedObject = [];
objects.forEach(function(item){
var obj = _.zipObject(headers, item);
populatedObject.push(obj);
});
.zipObject 方法会将每个 header 与 items 数组中的每个值匹配并生成一个 object。
使用ES6/ES7和一些函数式编程指南:
- 所有变量都是
const
(不变性) - 使用
map
/reduce
代替while
/for
- 所有功能都是箭头
- 无依赖关系
// Split data into lines and separate headers from actual data
// using Array spread operator
const [headerLine, ...lines] = data.split('\n');
// Split headers line into an array
// `valueSeparator` may come from some kind of argument
// You may want to transform header strings into something more
// usable, like `camelCase` or `lowercase-space-to-dash`
const valueSeparator = '\t';
const headers = headerLine.split(valueSeparator);
// Create objects from parsing lines
// There will be as much objects as lines
const objects = lines
.map( (line, index) =>
line
// Split line with value separators
.split(valueSeparator)
// Reduce values array into an object like: { [header]: value }
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
.reduce(
// Reducer callback
(object, value, index) => ({
...object,
[ headers[index] ]: value,
}),
// Initial value (empty JS object)
{}
)
);
console.log("Objects:", objects);
对于使用 ,
作为分隔符和引号字符串值的 CSV 文件,您可以使用此版本:
// Split data into lines and separate headers from actual data
// using Array spread operator
const [headerLine, ...lines] = data.split('\n');
// Use common line separator, which parses each line as the contents of a JSON array
const parseLine = (line) => JSON.parse(`[${line}]`);
// Split headers line into an array
const headers = parseLine(headerLine);
// Create objects from parsing lines
// There will be as much objects as lines
const objects = lines
.map( (line, index) =>
// Split line with JSON
parseLine(line)
// Reduce values array into an object like: { [header]: value }
.reduce(
(object, value, index) => ({
...object,
[ headers[index] ]: value,
}),
{}
)
);
return objects;
注意:对于大文件,最好使用流、生成器、迭代器等
如果您已经有一个数组并希望 csv header(第一行)成为 object 的 属性。
,那么这是一个解决方案
const csvArrayToObj = (csvData) => {
return csvData
.map((csvLine, csvIndex) => {
if (csvIndex === 0 || !csvLine.length) return null; // skip header and empty lines
return csvLine.reduce((a, v, i) => ({ ...a, [csvData[0][i]]: v }), {});
})
.filter((filter) => !!filter); //filter empty lines
};
const csvArray = [
['name', 'age'],
['John Doe', 20],
['Jane Doe', 30],
];
csvArrayToObj(csvArray);
// output
[
{
"name": "John Doe",
"age": 20
},
{
"name": "Jane Doe",
"age": 30
}
]