如何解析包含数组的 JS 对象以在 JavaScript 中的 json2csv 模块中使用?
How to parse JS Object containing arrays to use in json2csv module in JavaScript?
我有一个对象数组 (arr),其中每个对象如下所示:-
{
"name" : "someName",
"address" : "someAddress",
"attributes" : [
{
"attName" : "Sea",
},
{
"attName" : "Beach",
}
],
"values" : [
"2540",
"3345",
"2340"
]
}
数组“values”和“attributes”对于不同的对象可能具有不同数量的元素。
现在,当我使用此代码将此对象数组转换为 csv 时:
const json2csv = require('json2csv').parse;
const csvString = json2csv(arr);
我得到以下输出:
name, address, attributes, values
"someName","someAddress", [{"attName" : "Sea"},{"attName" : "Beach"}], ["2540", "3345", "2340"]
但是,我想要这样的 csv:
name, address, attName, attName, value, value, value
"someName","someAddress", "Sea", "Beach", "2540", "3345", "2340"
我知道 JSON 不允许多个键同名,但我不知道如何实现。
将一个数组列扩展为多个同名列是non-standard。
但是,如果你真的想这样做,你可以编写一个自定义函数来将对象数组转换为二维字符串数组。然后使用库将二维字符串数组转换为csv。
例如:
// import a library to convert 2d string array into csv string
let { to_csv } = require("@beenotung/tslib/csv");
// the sample object array
let records = [{
"name": "someName",
"address": "someAddress",
"attributes": [
{
"attName": "Sea",
},
{
"attName": "Beach",
}
],
"values": [
"2540",
"3345",
"2340"
]
}];
let csv = object_array_to_csv(records)
console.log(csv);
/* will print out below lines:
name,address,attName,attName,values,values,values
someName,someAddress,Sea,Beach,2540,3345,2340
*/
// convert an object array into csv text
function object_array_to_csv(objects) {
let records = objects.map(object_to_opt_list);
let titles = records.find(record => record.length > 0)
.map(field => field.key);
let values = records.map(record => record.map(field => field.value));
let rows = [titles, ...values];
let csv = to_csv(rows);
return csv;
}
// convert an object with string and array of string/object into 2d key-value array
function object_to_opt_list(object) {
let opt_list = [];
for (const [key, value] of Object.entries(object)) {
if (Array.isArray(value)) {
opt_list.push(...value_to_opt_list(key, value));
}
else {
opt_list.push({ key, value });
}
}
return opt_list;
}
// convert recursively expand the array/object value into 2d key-value array
function value_to_opt_list(key, value) {
if (Array.isArray(value)) {
return value.map(value => value_to_opt_list(key, value))
.reduce((acc, c) => acc.concat(c));
}
if (typeof value === "object") {
return object_to_opt_list(value);
}
return [{ key, value }];
}
我有一个对象数组 (arr),其中每个对象如下所示:-
{
"name" : "someName",
"address" : "someAddress",
"attributes" : [
{
"attName" : "Sea",
},
{
"attName" : "Beach",
}
],
"values" : [
"2540",
"3345",
"2340"
]
}
数组“values”和“attributes”对于不同的对象可能具有不同数量的元素。
现在,当我使用此代码将此对象数组转换为 csv 时:
const json2csv = require('json2csv').parse;
const csvString = json2csv(arr);
我得到以下输出:
name, address, attributes, values
"someName","someAddress", [{"attName" : "Sea"},{"attName" : "Beach"}], ["2540", "3345", "2340"]
但是,我想要这样的 csv:
name, address, attName, attName, value, value, value
"someName","someAddress", "Sea", "Beach", "2540", "3345", "2340"
我知道 JSON 不允许多个键同名,但我不知道如何实现。
将一个数组列扩展为多个同名列是non-standard。
但是,如果你真的想这样做,你可以编写一个自定义函数来将对象数组转换为二维字符串数组。然后使用库将二维字符串数组转换为csv。
例如:
// import a library to convert 2d string array into csv string
let { to_csv } = require("@beenotung/tslib/csv");
// the sample object array
let records = [{
"name": "someName",
"address": "someAddress",
"attributes": [
{
"attName": "Sea",
},
{
"attName": "Beach",
}
],
"values": [
"2540",
"3345",
"2340"
]
}];
let csv = object_array_to_csv(records)
console.log(csv);
/* will print out below lines:
name,address,attName,attName,values,values,values
someName,someAddress,Sea,Beach,2540,3345,2340
*/
// convert an object array into csv text
function object_array_to_csv(objects) {
let records = objects.map(object_to_opt_list);
let titles = records.find(record => record.length > 0)
.map(field => field.key);
let values = records.map(record => record.map(field => field.value));
let rows = [titles, ...values];
let csv = to_csv(rows);
return csv;
}
// convert an object with string and array of string/object into 2d key-value array
function object_to_opt_list(object) {
let opt_list = [];
for (const [key, value] of Object.entries(object)) {
if (Array.isArray(value)) {
opt_list.push(...value_to_opt_list(key, value));
}
else {
opt_list.push({ key, value });
}
}
return opt_list;
}
// convert recursively expand the array/object value into 2d key-value array
function value_to_opt_list(key, value) {
if (Array.isArray(value)) {
return value.map(value => value_to_opt_list(key, value))
.reduce((acc, c) => acc.concat(c));
}
if (typeof value === "object") {
return object_to_opt_list(value);
}
return [{ key, value }];
}