【问题标题】:Create nested array of object upto a limit创建对象的嵌套数组达到限制
【发布时间】:2020-07-20 15:52:16
【问题描述】:
I have an array of objects like this
    const ticketsData = [
            { id: 1, title: 'parent', parent: 0, url: '' },
            { id: 2, title: 'parent', parent: 0, url: '' },
            { id: 3, title: 'child', parent: 1, url: '' },
            { id: 4, title: 'sub child', parent: 3, url: '' },
            { id: 5, title: 'sub sub child', parent: 4, url: '' },
            { id: 6, title: 'sub sub sub child', parent: 5, url: '' },
            { id: 10, title: 'sub sub child 2', parent: 4, url: '' },
            { id: 13, title: 'sub child 2', parent: 3, url: '' },
            { id: 14, title: 'child', parent: 2, url: '' },
            { id: 7, title: 'sub sub sub child', parent: 5, url: '' },
            { id: 8, title: 'sub sub sub child', parent: 5, url: '' },
            { id: 9, title: 'sub sub sub child', parent: 5, url: '' },
            { id: 11, title: 'sub sub child 3', parent: 4, url: '' },
            { id: 12, title: 'sub sub child 4', parent: 4, url: '' }
          ];

我想创建一个嵌套的对象数组,直到一个限制,比如 10。所以当计数减少到零时,它应该返回数组直到那个孩子/父母。

> This is my expected Output:

    [{ id: 1, title: 'parent', parent: 0, url: '', children: [
{ id: 3, title: 'child', parent: 1, url: '', children:[
{ id: 4, title: 'sub child', parent: 3, url: '', children:[
{ id: 5, title: 'sub sub child', parent: 4, url: '' , children:[
{ id: 6, title: 'sub sub sub child', parent: 5, url: '', children:[] },
{ id: 7, title: 'sub sub sub child', parent: 5, url: '', children:[] },
{ id: 8, title: 'sub sub sub child', parent: 5, url: '', children:[] },
{ id: 9, title: 'sub sub sub child', parent: 5, url: '', children:[] }
]},
{ id: 10, title: 'sub sub child 2', parent: 4, url: '', children:[] },
{ id: 11, title: 'sub sub child 3', parent: 4, url: '', children:[] }
] }
] }
] }]

我试过了,但把所有对象放在单独的数组中。

     const createTicketTree = (tickets, count) => {
        let ticketObj = {};
        let ticketHierarchy = []
        tickets.map( ticket => {
          ticketObj[ticket.id] = { ...ticket, children: [] };
            if(ticket.parent && count && count--) {
              ticketObj[ticket.parent].children.push(ticketObj[ticket.id]) 
             }
            else { 
            ticketHierarchy.push(ticketObj[ticket.id]) 
            }
        });
        return ticketHierarchy;
    };

这就是我调用该函数以使嵌套的父子关系达到 10 的方式。 是否有任何 lodash/underscore 实现来实现这一点? 任何帮助将不胜感激

    createTicketTree(ticketsData, 10);

【问题讨论】:

  • 你有想要的结果的例子吗?
  • 分享预期的输出格式
  • @NinaScholz:更新了我的预期输出
  • 数组排序了吗?为什么不取前 n 个对象并从中构建一棵树?
  • 实际上我没有得到限制的意义。如果父级在计数中,您想要树的完整分支还是限制想要的嵌套部分的深度?

标签: javascript arrays ecmascript-6 nested lodash


【解决方案1】:

您可以将递归方法与reduce 方法一起使用,并将添加元素的计数保留在一个变量中,并检查计数是否小于 0 以停止向数组添加元素。

const ticketsData = [{"id":1,"title":"parent","parent":0,"url":""},{"id":2,"title":"parent","parent":0,"url":""},{"id":3,"title":"child","parent":1,"url":""},{"id":4,"title":"sub child","parent":3,"url":""},{"id":5,"title":"sub sub child","parent":4,"url":""},{"id":6,"title":"sub sub sub child","parent":5,"url":""},{"id":10,"title":"sub sub child 2","parent":4,"url":""},{"id":13,"title":"sub child 2","parent":3,"url":""},{"id":14,"title":"child","parent":2,"url":""},{"id":7,"title":"sub sub sub child","parent":5,"url":""},{"id":8,"title":"sub sub sub child","parent":5,"url":""},{"id":9,"title":"sub sub sub child","parent":5,"url":""},{"id":11,"title":"sub sub child 3","parent":4,"url":""},{"id":12,"title":"sub sub child 4","parent":4,"url":""}]

let count = 10;

function createTicketTree(data, pid = 0) {
  return data.reduce((r, e) => {
    if (e.parent === pid && count > 0) {
      count--
      const o = { ...e }
      const c = createTicketTree(data, e.id);
      if (c.length) o.children = c;
      r.push(o)
    }

    return r;
  }, [])
}

const result = createTicketTree(ticketsData);
console.log(result)

【讨论】:

  • 感谢@Nenad,这很完美。由于性能问题,有没有办法在不递归的情况下做到这一点?
  • 我指的是playcode.io/316025,我会接受这个答案,尽管性能上没有太大差异。再次感谢您挽救了我的一天。
  • 您可以像jsfiddle.net/qm9yghpe/4 这样添加一些优化,其中数据池越来越小。
  • 如果性能在这里很重要jsfiddle.net/6ozve92d/1,你也可以使用普通的 for 循环
  • 我们可以在函数内部使用这个计数变量吗?因为我必须从我的状态中将它传递给我的函数。
【解决方案2】:

我不认为 if 条件是您正在寻找的。 count 不会在任何地方修改或保存。我会修改 if 语句以检查父票的 children 的长度,与计数相比:

if(ticket.parent && ticketObj[ticket.parent].children.length < count)

但是,我对您正在寻找的最终结果以及您如何计算 children 列表中的嵌套对象感到困惑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-06
    • 2021-11-28
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 2022-01-02
    • 2020-12-21
    • 2019-04-23
    相关资源
    最近更新 更多