将对象数组转换为分层数据结构
Converting array of object to hierarchical data structure
我有一个原始数组,我想在需要分层数据结构的 Sunburst 地图中绘制它。
[
{id: "Asia,India,NewDelhi", value: 41},
{id: "Europe,Germany,Berlin", value: 24},
{id: "Europe,England,London", value: 3},
{id: "NorthAmerica,USA,NewYork", value: 4},
{id: "NorthAmerica,USA,Boston", value: 3},
{id: "NorthAmerica,USA,chicago", value: 3},
{id: "Austrailia,Sydney", value: 4},
{id: "Asia,China,Beijing", value: 2},
]
期望的结果
[
{
id: Asia,
children:[{
id: India,
children:[{
id: Delhi,
value: 41,
}]
},
{
id:China,
children:[{
id: Beijing
value: 2,
}]
}]
},
{
id: Europe,
children: [{
id: Germany,
children: [{
id: Berlin,
value: 24,
}]
},
{
id: England,
children: [{
id: London,
value: 3,
}]
}]
},
{
id: NorthAmerica,
children:[{
id: USA,
children:[{
id: NewYork,
value: 4,
},
{
id: Boston,
value: 3,
},
{
id: Chicago,
value: 3,
}]
}]
},
{
id: Austrailia
children: [{
id:Sydney,
value: 4,
}]
},
]
谁能帮我解决这个问题,我尝试使用 reduce 方法,但无法获得所需的结果。
PS :如果有人能提出一个可以处理 n 个用逗号分隔的 ID 的答案,那将非常有用。例如:这里我们有 3 个 id 层次结构,用逗号分隔,如果有 4 或 5 个深度数据会发生什么。
要根据您的输入构建 对象 的层次结构非常简单,您甚至不需要执行任何递归循环 + reduce
即可完成。这将适用于逗号分隔列表中的任意数量的级别。
const input = [
{id: "Asia,India,NewDelhi", value: 41},
{id: "Europe,Germany,Berlin", value: 24},
{id: "Europe,England,London", value: 3},
{id: "NorthAmerica,USA,NewYork", value: 4},
{id: "NorthAmerica,USA,Boston", value: 3},
{id: "NorthAmerica,USA,chicago", value: 3},
{id: "Austrailia,Sydney", value: 4},
{id: "Asia,China,Beijing", value: 2}
]
const result = input.map(o => ({ids:o.id.split(","), value:o.value})).reduce( (acc,obj) => {
let curr = acc;
let id;
while( (id = obj.ids.shift()) != null ){
if(!curr[id])
curr[id] = {};
curr = curr[id];
}
curr.value = obj.value
return acc;
},{});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
然后将其转换为您想要的格式确实需要一些递归:
const input = [
{id: "Asia,India,NewDelhi", value: 41},
{id: "Europe,Germany,Berlin", value: 24},
{id: "Europe,England,London", value: 3},
{id: "NorthAmerica,USA,NewYork", value: 4},
{id: "NorthAmerica,USA,Boston", value: 3},
{id: "NorthAmerica,USA,chicago", value: 3},
{id: "Austrailia,Sydney", value: 4},
{id: "Asia,China,Beijing", value: 2}
]
const result = input.map(o => ({ids:o.id.split(","), value:o.value})).reduce( (acc,obj) => {
let curr = acc;
let id;
while( (id = obj.ids.shift()) != null ){
if(!curr[id])
curr[id] = {};
curr = curr[id];
}
curr.value = obj.value
return acc;
},{});
function buildHierarchy(input){
return Object.entries(input).map( ([id,children]) => {
if(children.value){
return {id,value:children.value}
}
return {id, children: buildHierarchy(children)}
})
}
console.log(buildHierarchy(result));
.as-console-wrapper { max-height: 100% !important; top: 0; }
一个简单的递归解决方案:
const data = [
{id: "Asia,India,NewDelhi", value: 41},
{id: "Europe,Germany,Berlin", value: 24},
{id: "Europe,England,London", value: 3},
{id: "NorthAmerica,USA,NewYork", value: 4},
{id: "NorthAmerica,USA,Boston", value: 3},
{id: "NorthAmerica,USA,Chicago", value: 3},
{id: "Austrailia,Sydney", value: 4},
{id: "Asia,China,Beijing", value: 2},
];
const addChild = (ids, value, arr) => {
const id = ids.shift();
let index = arr.findIndex(item => item.id === id);
if (index < 0) {
arr.push({id, children: []});
index = arr.length - 1;
}
if (ids.length > 0) {
const children = arr[index].children;
addChild(ids, value, children);
}
else
arr[index].value = value;
}
const treeData = data.reduce((tree, item) => {
const ids = item.id.split(',');
addChild(ids, item.value, tree);
return tree;
}, []);
console.log(treeData);
我有一个原始数组,我想在需要分层数据结构的 Sunburst 地图中绘制它。
[
{id: "Asia,India,NewDelhi", value: 41},
{id: "Europe,Germany,Berlin", value: 24},
{id: "Europe,England,London", value: 3},
{id: "NorthAmerica,USA,NewYork", value: 4},
{id: "NorthAmerica,USA,Boston", value: 3},
{id: "NorthAmerica,USA,chicago", value: 3},
{id: "Austrailia,Sydney", value: 4},
{id: "Asia,China,Beijing", value: 2},
]
期望的结果
[
{
id: Asia,
children:[{
id: India,
children:[{
id: Delhi,
value: 41,
}]
},
{
id:China,
children:[{
id: Beijing
value: 2,
}]
}]
},
{
id: Europe,
children: [{
id: Germany,
children: [{
id: Berlin,
value: 24,
}]
},
{
id: England,
children: [{
id: London,
value: 3,
}]
}]
},
{
id: NorthAmerica,
children:[{
id: USA,
children:[{
id: NewYork,
value: 4,
},
{
id: Boston,
value: 3,
},
{
id: Chicago,
value: 3,
}]
}]
},
{
id: Austrailia
children: [{
id:Sydney,
value: 4,
}]
},
]
谁能帮我解决这个问题,我尝试使用 reduce 方法,但无法获得所需的结果。
PS :如果有人能提出一个可以处理 n 个用逗号分隔的 ID 的答案,那将非常有用。例如:这里我们有 3 个 id 层次结构,用逗号分隔,如果有 4 或 5 个深度数据会发生什么。
要根据您的输入构建 对象 的层次结构非常简单,您甚至不需要执行任何递归循环 + reduce
即可完成。这将适用于逗号分隔列表中的任意数量的级别。
const input = [
{id: "Asia,India,NewDelhi", value: 41},
{id: "Europe,Germany,Berlin", value: 24},
{id: "Europe,England,London", value: 3},
{id: "NorthAmerica,USA,NewYork", value: 4},
{id: "NorthAmerica,USA,Boston", value: 3},
{id: "NorthAmerica,USA,chicago", value: 3},
{id: "Austrailia,Sydney", value: 4},
{id: "Asia,China,Beijing", value: 2}
]
const result = input.map(o => ({ids:o.id.split(","), value:o.value})).reduce( (acc,obj) => {
let curr = acc;
let id;
while( (id = obj.ids.shift()) != null ){
if(!curr[id])
curr[id] = {};
curr = curr[id];
}
curr.value = obj.value
return acc;
},{});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
然后将其转换为您想要的格式确实需要一些递归:
const input = [
{id: "Asia,India,NewDelhi", value: 41},
{id: "Europe,Germany,Berlin", value: 24},
{id: "Europe,England,London", value: 3},
{id: "NorthAmerica,USA,NewYork", value: 4},
{id: "NorthAmerica,USA,Boston", value: 3},
{id: "NorthAmerica,USA,chicago", value: 3},
{id: "Austrailia,Sydney", value: 4},
{id: "Asia,China,Beijing", value: 2}
]
const result = input.map(o => ({ids:o.id.split(","), value:o.value})).reduce( (acc,obj) => {
let curr = acc;
let id;
while( (id = obj.ids.shift()) != null ){
if(!curr[id])
curr[id] = {};
curr = curr[id];
}
curr.value = obj.value
return acc;
},{});
function buildHierarchy(input){
return Object.entries(input).map( ([id,children]) => {
if(children.value){
return {id,value:children.value}
}
return {id, children: buildHierarchy(children)}
})
}
console.log(buildHierarchy(result));
.as-console-wrapper { max-height: 100% !important; top: 0; }
一个简单的递归解决方案:
const data = [
{id: "Asia,India,NewDelhi", value: 41},
{id: "Europe,Germany,Berlin", value: 24},
{id: "Europe,England,London", value: 3},
{id: "NorthAmerica,USA,NewYork", value: 4},
{id: "NorthAmerica,USA,Boston", value: 3},
{id: "NorthAmerica,USA,Chicago", value: 3},
{id: "Austrailia,Sydney", value: 4},
{id: "Asia,China,Beijing", value: 2},
];
const addChild = (ids, value, arr) => {
const id = ids.shift();
let index = arr.findIndex(item => item.id === id);
if (index < 0) {
arr.push({id, children: []});
index = arr.length - 1;
}
if (ids.length > 0) {
const children = arr[index].children;
addChild(ids, value, children);
}
else
arr[index].value = value;
}
const treeData = data.reduce((tree, item) => {
const ids = item.id.split(',');
addChild(ids, item.value, tree);
return tree;
}, []);
console.log(treeData);