【问题标题】:Merge array of arrays based sub array index as keys (NodeJS/Javascript)将基于子数组索引的数组数组合并为键(NodeJS/Javascript)
【发布时间】:2020-12-18 10:43:32
【问题描述】:

如何编写代码以下列方式合并我的列表?性能很重要。我想转换以下数组:

"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: []
                        },
                    }
             ]
     },
]

子数组的第一个索引是父级,第二个索引是父级的子级,第三个索引是第二个索引的子级(依此类推)。

【问题讨论】:

  • 什么不起作用?请添加您的代码。
  • 您的预期输出不是有效的 Javascript,
  • @Keith 预期的输出是 json。现在我将它转换为 JS 对象以使其更容易。我只需要帮助将上述数组转换为输出。任何参考都会有帮助。

标签: javascript node.js arrays reactjs


【解决方案1】:

最短的方法是迭代嵌套名称并查找具有相同名称的对象。如果不存在,则创建一个新对象。将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; }

【讨论】:

    【解决方案2】:

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

    我要做的是循环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%;
    }

    【讨论】:

      【解决方案3】:

      您可以执行以下操作,

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

      【讨论】:

        【解决方案4】:

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

        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)复杂度。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-01-10
          • 1970-01-01
          • 2013-06-17
          • 2018-06-12
          • 1970-01-01
          • 1970-01-01
          • 2018-09-13
          相关资源
          最近更新 更多