Javascript 将字符串转换为嵌套对象和数组

Javascript 将字符串转换为嵌套对象和数组,javascript,arrays,object,contentful,Javascript,Arrays,Object,Contentful,我在一个项目中,前一个家伙做了一些奇怪的路由,基本上我从contentful中得到了字符串形式的slug,我将其放入数组[“/api/”、“/docs/getting start/”、“/docs/”、“/plugin/”、“/plugin/user/”、“/plugin/profile/”…] 现在我需要把它转换成数组的形式 let cleanedSidebarContents = [{ title:null, pages:[

我在一个项目中,前一个家伙做了一些奇怪的路由,基本上我从contentful中得到了字符串形式的slug,我将其放入数组
[“/api/”、“/docs/getting start/”、“/docs/”、“/plugin/”、“/plugin/user/”、“/plugin/profile/”…]

现在我需要把它转换成数组的形式

let cleanedSidebarContents = [{
              title:null,
              pages:[
                     {title:"api",
                      path:"/api/"
                      },
                     {title:"docs",
                      path:"/docs/"
                      },
                      {title:"plugin",
                      path:"/plugin/"
                      },
                     ]
               },
             {
              title:"plugin",
              pages:[
                     {title:"user",
                      path:"/plugin/user/"
                      },
                     {title:"profile",
                      path:"/plugin/profile/"
                      },
                     ]
               },
              {
              title:"docs",
              pages:[
                     {title:"getting-started",
                      path:"/plugin/getting-started/"
                      },
                     ]
               }
]
所以我现在做的是-

 //-------Format sidebar data--------------->
    let cleanedSidebarContents = [];
    (function cleanSidebarContents() {

        let sideBarContentsContentful = [];
        cleanContentfulEdges.forEach(edge => {
            let slug = edge.node.slug;
            //split string into titles and remove empty spaces
            let routeMapArray = slug.split("/").filter(x => x != "");
            if (routeMapArray.length > 1) {
                sideBarContentsContentful.push({
                    title: routeMapArray[0],
                    page: {
                        title: routeMapArray[routeMapArray.length - 1],
                        path: edge.node.slug
                    }
                });
            } else {
                sideBarContentsContentful.push({
                    title: null,
                    page: {
                        title: routeMapArray[routeMapArray.length - 1],
                        path: edge.node.slug
                    }
                });
            }
        });

        let titles = [];
        for (let i = 0; i < sideBarContentsContentful.length; i++) {
            titles.push(sideBarContentsContentful[i].title);
        }
        //clean duplicate entries
        titles = titles.filter(function (item, index, inputArray) {
            return inputArray.indexOf(item) === index;
        });
        titles.sort();

        titles.map(item => {
            cleanedSidebarContents.push({
                title: item,
                pages: []
            })
        });

        sideBarContentsContentful.forEach(item => {
            for (let i = 0; i < cleanedSidebarContents.length; i++) {
                if(cleanedSidebarContents[i].title === item.title){
                    cleanedSidebarContents[i].pages.push(item.page)
                }
            }
        });
    }());
    //----------------------------------------->
/----格式化侧边栏数据----------------->
让cleanedSidebarContents=[];
(函数cleanSidebarContents(){
让侧边栏内容content=[];
CleanContentfulEdge.forEach(edge=>{
设slug=edge.node.slug;
//将字符串拆分为标题并删除空格
让routeMapArray=slug.split(“/”).filter(x=>x!=”);
如果(routeMapArray.length>1){
侧边栏内容content.push({
标题:路由阵列[0],
第页:{
标题:routeMapArray[routeMapArray.length-1],
路径:edge.node.slug
}
});
}否则{
侧边栏内容content.push({
标题:空,
第页:{
标题:routeMapArray[routeMapArray.length-1],
路径:edge.node.slug
}
});
}
});
让标题=[];
for(设i=0;i{
cleanedSidebarContents.push({
标题:项目,
页码:[]
})
});
侧边栏内容content.forEach(项=>{
for(设i=0;i
我首先拆分所有字符串并将标题放入标题数组中,然后删除重复项并相应地映射数据


我只是觉得这是非常糟糕的代码,有一种更好的方法我就是想不出来。

你可以创建一个
映射器
对象,它映射输出中的对象,每个对象的根中都有
标题。
/
处拆分
,以获得所有路径块。
.filter(布尔值)
删除从字符串开头和结尾创建的所有空字符串。如果只有一个匹配项,则它属于默认的
null
对象。否则,使用
匹配项中的第一个键作为累加器中的键

const-input=[“/api/”、“/docs/getting start/”、“/docs/”、“/plugin/”、“/plugin/user/”、“/plugin/profile/”];
常量映射器=输入。减少((acc,路径)=>{
让matches=path.split(/\/).filter(布尔),
mapperKey=null;
如果(匹配。长度>1)
mapperKey=匹配项[0];
如果(!acc[mapperKey])
acc[mapperKey]={标题:mapperKey,页码:[]};
const title=matches.pop();
acc[mapperKey].pages.push({title,path});
返回acc;
}, {})
常量输出=对象值(映射器);

console.log(输出)
您好,我想这不是您的问题所在。这更像是一个与代码审查相关的问题。这里我们问一些对其他人也有帮助的特定主题。试试这里:谢谢,它有效,我不知道如何工作,但我会研究它。干杯!@Jaykch这个想法是在输出数组中使用相同的对象和映射器对象的值。对于例如,创建了一个对象,如
pluginObject={title:“plugin”,pages:[..]}
。在
mapper[“plugin”]=pluginObject
output.push(pluginObject)
中使用同一对象的引用。因此,如果找到一个以“plugin”开头的路径,只需将其推送到
mapper[“plugin”].pages
数组。这也会更新输出数组中的对象,因为它们都指向同一个对象。您不必遍历数组并检查是否有任何对象具有
标题:“插件”“
我已将其更新为使用
reduce
并将正则表达式简化为使用split。谢谢,我现在查看了它,奇怪的是,我想我无法在javascript中找到数组[key]。现在看起来很愚蠢。非常感谢你。