0

我有一个原始数组,我想将它绘制在需要分层数据结构的 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 个深度数据会发生什么。

4

2 回答 2

1

一个简单的递归解决方案:

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);

于 2021-04-21T16:32:04.163 回答
0

从您的输入构建对象层次结构非常简单,您甚至不需要做任何递归循环 +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; }

于 2021-04-21T16:24:34.760 回答