为了账号安全,请及时绑定邮箱和手机立即绑定

合并基于子数组索引的数组数组作为键(NodeJS/Javascript)

合并基于子数组索引的数组数组作为键(NodeJS/Javascript)

慕妹3242003 2023-12-14 14:36:24
如何编写代码以以下方式合并我的列表?性能很重要。我想转换以下数组:"list": [    [        "marketing",        "page_sections",        "PageOne"    ],    [        "marketing",        "page_sections",        "PageTwo"    ],    [        "webapp",        "page",        "pageone"    ],    [        "webapp",        "page",        "pagetwo"    ],改成下面的格式:[       {     name: "marketing",     path: "marketing/",                children: [                    {                        name: "page_sections",                        path: "marketing/page_sections",                         children: [                            {                                name: "pageOne",                                path: "marketing/page_sections/pageOne",                                 children: []                            },                            {                                name: "pageTwo",                                path: "marketing/page_sections/pageTwo",                                 children: []                            },                       }           ],     },    {     name: "webapp",     path: "webapp/"     children: [                  {                    name: "page",                    path: "webapp/page/"                                        children: [                        {                            name: "pageone",                            path: "webapp/page/pageone"                            children: []                        },                        {                            name: "pagetwo",                            path: "webapp/page/pagetwo"                            children: []                        },                    }             ]     },]子数组的第一个索引是父级,第二个索引是父级的子级,第三个索引是第二个索引的子级(依此类推)。
查看完整描述

4 回答

?
MM们

TA贡献1886条经验 获得超2个赞

最短的方法是迭代嵌套名称并查找具有相同名称的对象。如果不存在,则创建一个新对象。将数组返回children为新级别。

此方法的特点Array#reduce是迭代外部数组data和所有内部数组。

const

    data = [["marketing", "page_sections", "PageOne"], ["marketing", "page_sections", "PageTwo"], ["webapp", "page", "pageone"], ["webapp", "page", "pagetwo"]],

    result = data.reduce((r, names) => {

        names.reduce((level, name, i, values) => {

            let temp = level.find(q => q.name === name),

                path = values.slice(0, i + 1).join('/') + (i ? '' : '/');

            if (!temp) level.push(temp = { name, path, children: [] });

            return temp.children;

        }, r);

        return r;

    }, []);


console.log(result);

.as-console-wrapper { max-height: 100% !important; top: 0; }


查看完整回答
反对 回复 2023-12-14
?
哔哔one

TA贡献1854条经验 获得超8个赞

查看来源以及您的预期结果。


我要做的是循环list,然后在列表中进行另一个循环。将此与Array.find..混合


例如..


const data = {list:[

  ["marketing","page_sections","PageOne"],

  ["marketing","page_sections","PageTwo"],

  ["webapp","page","pageone"],

  ["webapp","page","pagetwo"]]};

  


function makeTree(src) {

  const root = [];

  for (const s of src) {

    let r = root;

    let path = '';

    for (const name of s) {

      path += `${name}/`;

      let f = r.find(k => k.name === name);

      if (!f) r.push(f = {name, path, children: []});

      r = f.children;

    }

  }

  return root;

}

   

console.log(makeTree(data.list));

.as-console-wrapper {

  min-height: 100%;

}


查看完整回答
反对 回复 2023-12-14
?
鸿蒙传说

TA贡献1865条经验 获得超7个赞

您可以执行以下操作,


list= [

    [

        "marketing",

        "page_sections",

        "PageOne"

    ],

    [

        "marketing",

        "page_sections",

        "PageTwo"

    ],

    [

        "webapp",

        "page",

        "pageone"

    ],

    [

        "webapp",

        "page",

        "pagetwo"

    ],

  ];



getChildrenItem = (arr) => {

  if(arr.length === 1) {

    return { name: arr[0], children: []};

  } else {

    return { name: arr.splice(0,1)[0], children: [getChildrenItem([...arr])]};

  }

  

}


merge = (srcArr, newObj) => {

  const {name, children} = newObj;

  let index = srcArr.findIndex(item => item.name === name);

  if( index> -1) {

    children.forEach(item => merge(srcArr[index].children, item))

    return ;

  } else {

    srcArr.push(newObj);

    return;

  }

}


allObj = [];

list.forEach(item => {

  let tempObj = getChildrenItem([...item]);

  merge(allObj, tempObj);

});


console.log(allObj);


查看完整回答
反对 回复 2023-12-14
?
翻过高山走不出你

TA贡献1875条经验 获得超3个赞

如果性能是一个问题,我认为这是最好的解决方案之一。


let list = [

  ["marketing", "page_sections", "PageOne"],

  ["marketing", "page_sections", "PageTwo"],

  ["webapp", "page", "pageone"],

  ["webapp", "page", "pagetwo"],

];

const dt = {};

const pushToOBJ = (Object, name) => {

  if (Object[name]) return Object[name];

  Object[name] = {

    name,

    children: {},

  };

  return Object[name];

};


for (let i = 0; i < list.length; i++) {

  let subArray = list[i];

  let st = pushToOBJ(dt, subArray[0]);

  for (let j = 1; j < subArray.length; j++) {

    st = pushToOBJ(st.children, subArray[j]);

  }

}

let result = [];

const convertObjToChildArray = (obj) => {

  if (obj === {}) return [];


  let arr = Object.values(obj);

  for (let i = 0; i < arr.length; i++) {

    arr[i].children = convertObjToChildArray(arr[i].children);

  }

  return arr;

};

result = convertObjToChildArray(dt);

console.log(result);

没有使用 JS find 函数,该函数已经具有 O(n) 复杂度。


查看完整回答
反对 回复 2023-12-14
  • 4 回答
  • 0 关注
  • 131 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信