【问题标题】:Converting an array to an object of nested objects for a tree diagram in Javascript在Javascript中将数组转换为树形图的嵌套对象的对象
【发布时间】:2021-06-17 17:33:19
【问题描述】:

我正在尝试使用 react-d3-js 创建树形图。它需要采用特定格式。所以我需要将我拥有的初始数据转换为格式。

这是一个商店查看分销链以及允许谁从特定节点进行购买的图表。

初始数据:

store.name = 'Absolut Chocolat' //Main Parent


store.shopconditions: [
    {
        "role": "agent",
        "condition": ["owner", "stokist"]
    }, 
    {
        "role": "stokist",
        "condition": ["owner", "master stokist"]
    },
    {
        "role": "master stokist",
        "condition": ["owner"]
    }
    ]

// If role is agent, then they are allowed to buy from 'owner' and 'stokist'

这是硬编码的理想输出:

  orgChart = {
    name: 'Absolut Chocolat',
    children: [
      { name: 'Agent' },
      {
        name: 'Stokist',
        children: [
          {
            name: 'Agent',
          },
        ],
      },
      {
        name: 'Master Stokist',
        children: [
          {
            name: 'Stokist',
            children: [
              {
                name: 'Agent',
              },
            ],
          },
        ],
      },
    ],
  };

每个循环都有几个,我已经到达预期输出的前 2 层,但我找不到更多的方法。

这是我目前得到的: Agent node is not under Master Stokist

当前代码:

  let chartData = { name: store.name, children: [] };

  store.shopconditions.forEach((i) => {
    i.condition.forEach((c) => {
      if (c === 'owner') {
        chartData.children.push({ name: i.role });
      }
    });
  });

  const chartDataParser = (data) => {

    data.children.map((i) => {
      for (const [k, v] of Object.entries(i)) {
        store.shopconditions.forEach((c) => {
          c.condition.forEach((o) => {
            if (o === v) {
              if (!i.children) {
                i.children = [{ name: c.role }];
              } else {
                i.children.push({ name: c.role });
              }
            }
          });
        });
      }
    });
  };

  chartDataParser(chartData);

当前输出:

{
    name: 'Absolut Chocolat',
    children: [
      { name: 'Agent' },
      {
        name: 'Stokist',
        children: [
          {
            name: 'Agent',
          },
        ],
      },
      {
        name: 'Master Stokist',
        children: [
          {
            name: 'Stokist',
            // Missing children: Agent Node
          },
        ],
      },
    ],
  };

树形图应该是什么样子: As you can see under Master Stokist node, Agent is under Stokist

在最右边链中的 stokist 节点下未到达代理节点。我需要修复我当前的代码,以便它可以转到那个额外的层。提前致谢。期待从您的回答中学习。

【问题讨论】:

    标签: javascript reactjs d3.js


    【解决方案1】:

    您可以构建一个按角色列出子级的对象,然后使用它递归地构建对象的节点。可能类似于以下内容:

    const store = {
      name: 'Absolut Chocolat',
      shopconditions: [
        { "role": "agent", "condition": ["owner", "stokist"], name: 'Agent' }, 
        { "role": "stokist", "condition": ["owner", "master stokist"], name: 'Stockist' },
        { "role": "master stokist", "condition": ["owner"], name: 'Master Stockist' },
      ]
    };
    
    const build_role_map = (store) => {
      let role_map = Object.fromEntries(
        store.shopconditions.map((v) => [v.role, { ...v, children: [] }])
      );
      role_map.owner = { "role": "owner", "condition": [], children: [], name: store.name };
    
      store.shopconditions.forEach(
        ({ role, condition }) => {
          condition.forEach((parent) => { role_map[parent].children.push(role) })
        }
      );
      
      return role_map;
    };
    
    const build_node = (role_map, { name, children }) => {
      let node = { name };
      
      if(children.length > 0)
        node.children = children.map((child) => build_node(role_map, role_map[child]));
      
      return node;
    };
    
    const build_tree = (store) => {
      const role_map = build_role_map(store);
      
      return build_node(role_map, role_map.owner);
    };
    
    console.log(build_tree(store));

    【讨论】:

      猜你喜欢
      • 2018-01-24
      • 1970-01-01
      • 1970-01-01
      • 2020-07-07
      • 2016-04-13
      • 1970-01-01
      • 2022-12-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多