将csv文件数据转换为JavaScript字典



CSV文件数据:

parent_name, child_name
A1, A2
A1, A3
A1, A4
A1, A5
A2, A12
A2, A16
A2, A18
A2, A19

输出:要制作的Javascript对象

{
name: A1,
children: [
{
name: A2,
children: [
{
name: A4,
children: []
}
]
},
{
name: A3,
children: []
}
}

基本上,我必须转换一个CSV文件才能在d3中生成一个树。我想知道如何从CSV文件中制作所需的词典

d3.csv("test1.csv").then(function (data) {
var dataset = {};
data.forEach(function (d,i){
console.log(d.parent_name, d.child_name);
if(i === 0){
dataset["name"]  = d.parent_name;
dataset["children"] = [];
}
if (dataset["name"] === d.parent_name){
dataset.children.push(NodeMaker(d.child_name))
}
});
function NodeMaker(name){
return {"name": name, "children": []};
}
console.log(dataset);
});

这就是我的代码,我只做了一本字典,它不会比根节点的第一级更深

{
name: A1,
children: [
{
name: A2,
children: []
},
{
name: A3,
children: []
}
]
}

当前您只检查节点是否与根(第一个(节点匹配。一种想法可能是遍历现有的树,检查要添加的父节点是否已经存在,然后向其添加子节点。但这有一些问题:它需要返回数据,因此效率低下;如果你遇到一个parent_node,它还不是树的一部分,会发生什么?正如vicatcu所指出的,一种更有效(更稳健(的方法是在遇到节点时创建节点,并将它们保存在字典/查找对象中。

它可能看起来像这样:

var sampleData = [
{ parent_name: 'A1', child_name: 'A2' },
{ parent_name: 'A1', child_name: 'A3' },
{ parent_name: 'A1', child_name: 'A4' },
{ parent_name: 'A1', child_name: 'A5' },
{ parent_name: 'A2', child_name: 'A12' },
{ parent_name: 'A2', child_name: 'A16' },
{ parent_name: 'A2', child_name: 'A18' },
{ parent_name: 'A2', child_name: 'A19' }
]
// if loading from a file, use this line instead to load data
// d3.csv("test1.csv").then(function (data) {
Promise.resolve(sampleData).then(function (data) {
var lookup = {};
data.forEach(function (d,i) {
var parentNode = getNode(d.parent_name);
parentNode.children.push(getNode(d.child_name));
});
function getNode(name) {
if (!lookup[name]) {
// if the node doesn't exist, make it
lookup[name] = NodeMaker(name);
}
return lookup[name];
}
function NodeMaker(name){
return {"name": name, "children": []};
}
// if the first parent node is the root, it represents the whole tree
var tree = lookup[data[0].parent_name];
console.log(tree);
// do something with `tree`
});

您可以使用一个对象来保持所有关系,并添加未知节点作为根节点。

const
data = [['A1', 'A2'], ['A1', 'A3'], ['A2', 'A4']],
tree = function (data) {
const t = { root: { children: [] } };
data.forEach(([parent, name]) => {
t[name] = t[name] || { name, children: [] };
if (!t[parent]) t.root.children.push(t[parent] = { name: parent, children: [] });
t[parent].children.push(t[name]);

});
return t.root.children;
}(data);
console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }

首先使用一些库解析它(我通常使用csv解析(。接下来,对生成的数组进行迭代,并通过将每个记录添加到树中逐步构建最终的数据结构,当然,这涉及到为每一行确定应该如何更改树(无论是添加子项还是添加同级项或其他什么(。我建议的一种效率是为树中的对象设置一个名称字典,以避免搜索它们,比如{id:noderef},这样你就可以在恒定的时间内找出父对象是否存在以及在树中的位置。为了便于参考,csv格式在文献中有时被称为邻接矩阵。

最新更新