如何使用JavaScript将具有层次关系的csv文件转换为对象



我有一个csv文件,其中包含组织层次结构数据,其中一个字段是该员工下属id的id。

csv文件如下所示:

id,name,title,children
n1,Lao Lao,general manager,"n2,n3,n9,n10"
n2,Bo Miao,department manager
n3,Su Miao,department manager,"n4,n5,n8"
n4,Tie Hua,senior engineer
n5,Hei Hei,senior engineer,"n6,n7"
n6,Dan Dan,engineer
n7,Xiang Xiang,engineer
n8,Pang Pang,senior engineer
n9,Hong Miao,department manager
n10,Chun Miao,department manager,"n11"
n11,Yue Yue,senior engineer

我正在寻找的最终结果是这样的:

{
id: "n1",
name: "Lao Lao",
title: "general manager",
children: [
{ id: "n2", name: "Bo Miao", title: "department manager" },
{
id: "n3",
name: "Su Miao",
title: "department manager",
children: [
{ id: "n4", name: "Tie Hua", title: "senior engineer" },
{
id: "n5",
name: "Hei Hei",
title: "senior engineer",
children: [
{ id: "n6", name: "Dan Dan", title: "engineer" },
{ id: "n7", name: "Xiang Xiang", title: "engineer" },
],
},
{ id: "n8", name: "Pang Pang", title: "senior engineer" },
],
},
{ id: "n9", name: "Hong Miao", title: "department manager" },
{
id: "n10",
name: "Chun Miao",
title: "department manager",
children: [{ id: "n11", name: "Yue Yue", title: "senior engineer" }],
},
],
}

到目前为止,我已经尝试过:到目前为止,我已经使用csvtojson包将csv文件解析为一个数组,这给了我以下信息:

[
{
id: 'n1',
name: 'Lao Lao',
title: 'general manager',
children: 'n2,n3,n9,n10'
},
{ id: 'n2', name: 'Bo Miao', title: 'department manager' },
{
id: 'n3',
name: 'Su Miao',
title: 'department manager',
children: 'n4,n5,n8'
},
{ id: 'n4', name: 'Tie Hua', title: 'senior engineer' },
{
id: 'n5',
name: 'Hei Hei',
title: 'senior engineer',
children: 'n6,n7'
},
{ id: 'n6', name: 'Dan Dan', title: 'engineer' },
{ id: 'n7', name: 'Xiang Xiang', title: 'engineer' },
{ id: 'n8', name: 'Pang Pang', title: 'senior engineer' },
{ id: 'n9', name: 'Hong Miao', title: 'department manager' },
{
id: 'n10',
name: 'Chun Miao',
title: 'department manager',
children: 'n11'
},
{ id: 'n11', name: 'Yue Yue', title: 'senior engineer' }
]

我认为转换这些数据需要一些递归,但我不是很擅长,任何帮助都很感激!

编辑:此外,我对csv中的列的外观很灵活,如果有什么办法可以通过更改列来简化这种转换的话,那也很酷。

编辑:我正在考虑在csv中填写一份报告,我认为这会让它变得更容易;

id,name,title,report_to
n1,Lao Lao,general manager
n2,Bo Miao,department manager,n1
n3,Su Miao,department manager,n1,
n4,Tie Hua,senior engineer,n3
n5,Hei Hei,senior engineer,n3,
n6,Dan Dan,engineer,n5
n7,Xiang Xiang,engineer,n5
n8,Pang Pang,senior engineer,n3
n9,Hong Miao,department manager,n1
n10,Chun Miao,department manager,n1
n11,Yue Yue,senior engineer,n10

编辑:在我更改csv列后,我能够想出一个解决方案。我会把它贴在下面,以防其他人在未来寻找它。

const source = await CSVToJSON().fromFile("./example.csv");
const dataForOrgChart = source
.map((employee) => {
employee.children = source.filter(
(child) => child.report_to === employee.id
);
return employee;
})
.map((employee) => {
delete employee.report_to;
return employee;
})
.filter(
(employee) =>
!source
.map((employee) => employee.children.map((child) => child.id))
.reduce((acc, cur) => [...acc, ...cur], [])
.includes(employee.id)
)[0];
console.log(JSON.stringify(dataForOrgChart));

我甚至不能100%确定我是怎么来到这里的,这只是一大堆的考验。它似乎在工作,但如果有人注意到任何错误,请指出。也非常感谢不同的方法。我要把它们都学会!我是stackoverflow的新手,这是一个热烈的欢迎!

我在这个链接的帮助下创建了以下代码片段,这个解决方案可能会对您有所帮助。

// csv data parsing function from 
// https://stackoverflow.com/questions/1293147/javascript-code-to-parse-csv-data
var parseCSV2 = function(s, sep) {
// http://stackoverflow.com/questions/1155678/javascript-string-newline-character
var universalNewline = /rn|r|n/g;
var a = s.split(universalNewline);
for (var i in a) {
for (var f = a[i].split(sep = sep || ","), x = f.length - 1, tl; x >= 0; x--) {
if (f[x].replace(/"s+$/, '"').charAt(f[x].length - 1) == '"') {
if ((tl = f[x].replace(/^s+"/, '"')).length > 1 && tl.charAt(0) == '"') {
f[x] = f[x].replace(/^s*"|"s*$/g, '').replace(/""/g, '"');
} else if (x) {
f.splice(x - 1, 2, [f[x - 1], f[x]].join(sep));
} else f = f.shift().split(sep).concat(f);
} else f[x].replace(/""/g, '"');
}
a[i] = f;
}
return a;
}
//the CSV data
var csvData = `id,name,title,children
n1,Lao Lao,general manager,"n2,n3,n9,n10"
n2,Bo Miao,department manager
n3,Su Miao,department manager,"n4,n5,n8"
n4,Tie Hua,senior engineer
n5,Hei Hei,senior engineer,"n6,n7"
n6,Dan Dan,engineer
n7,Xiang Xiang,engineer
n8,Pang Pang,senior engineer
n9,Hong Miao,department manager
n10,Chun Miao,department manager,"n11"
n11,Yue Yue,senior engineer`;
//add nested employeess
function addtoDepartment(employeesArray, employee) {
if (!employee.addedToDepartement) {
let departmentEmp = {
id: employee.id,
name: employee.name,
title: employee.title
};
if (employee.childrenId) {
employee.childrenId.split(",").forEach(id => {
let emp = employeesArray.find(e => e.id == id);
let dep = addtoDepartment(employeesArray, emp);
if (dep) {
if (!departmentEmp.children)
departmentEmp.children = [];
departmentEmp.children.push(dep)
}
})
}
employee.addedToDepartement = true;
return departmentEmp;
}
return false;
}
let employeParsed = parseCSV2(csvData, ",");
let employees = [];
//add CSV emplyee data as employee object to an array
for (let i = 1; i < employeParsed.length; i++) {
empData = employeParsed[i];
employees.push({
id: empData[0] || '',
name: empData[1] || '',
title: empData[2] || '',
childrenId: empData[3],
addedToDepartement: false
});
}
//add employees to departments or under supervisor
var department = [];
for (let i = 0; i < employees.length; i++) {
let depEmp = addtoDepartment(employees, employees[i]);
if (depEmp)
department.push(depEmp);
}
//FINAL output
console.log(department);

如果id都不同,您可以将csv转换为一个漂亮的映射:您可以尝试执行以下操作:

let parsed = [
{
id: 'n1',
name: 'Lao Lao',
title: 'general manager',
children: 'n2,n3,n9,n10'
},
{ id: 'n2', name: 'Bo Miao', title: 'department manager' },
{
id: 'n3',
name: 'Su Miao',
title: 'department manager',
children: 'n4,n5,n8'
},
{ id: 'n4', name: 'Tie Hua', title: 'senior engineer' },
{
id: 'n5',
name: 'Hei Hei',
title: 'senior engineer',
children: 'n6,n7'
},
{ id: 'n6', name: 'Dan Dan', title: 'engineer' },
{ id: 'n7', name: 'Xiang Xiang', title: 'engineer' },
{ id: 'n8', name: 'Pang Pang', title: 'senior engineer' },
{ id: 'n9', name: 'Hong Miao', title: 'department manager' },
{
id: 'n10',
name: 'Chun Miao',
title: 'department manager',
children: 'n11'
},
{ id: 'n11', name: 'Yue Yue', title: 'senior engineer' }
];
let mapping = {};
parsed.forEach(v => mapping[v.id] = v); // Maps out employees
function organize(key) {
if (!mapping[key]) return;
if (typeof mapping[key].children === 'string') {
let children = {};
mapping[key].children.split(',').forEach(child => {
child = mapping[child];
children[child.id] = organize(child.id);
delete mapping[child.id];
});
mapping[key].children = children;
}
return mapping[key];
}
Object.keys(mapping).forEach(organize);
console.log(mapping);

最新更新