将字符串转换为嵌套的 objects 和数组
Convert string into nested objects and arrays
我在一个项目中,前一个人做了一些奇怪的路由,基本上我以字符串的形式从 contentful 中获取了 slug,我将其放入数组中 ["/api/", "/docs/getting-started/", "/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)
}
}
});
}());
//----------------------------------------->
我首先拆分所有字符串并将标题放入标题数组,然后删除重复项并相应地映射数据。
我只是觉得这是非常糟糕的代码,还有更好的方法我只是想不出来。
您可以创建一个 mapper
对象,它将输出中的对象映射到每个对象根中的 title
。 split
在 /
获取所有路径块。 .filter(Boolean)
删除从字符串开头和结尾创建的所有空字符串。如果只有一个匹配项,那么它属于默认的 null
对象。否则,使用 matches
中的第一个键作为累加器中的键。
const input = ["/api/", "/docs/getting-started/", "/docs/", "/plugin/", "/plugin/user/", "/plugin/profile/"];
const mapper = input.reduce((acc, path) => {
let matches = path.split(/\//).filter(Boolean),
mapperKey = null;
if (matches.length > 1)
mapperKey = matches[0];
if (!acc[mapperKey])
acc[mapperKey] = { title: mapperKey, pages: [] };
const title = matches.pop();
acc[mapperKey].pages.push({ title, path });
return acc;
}, {})
const output = Object.values(mapper);
console.log(output)
我在一个项目中,前一个人做了一些奇怪的路由,基本上我以字符串的形式从 contentful 中获取了 slug,我将其放入数组中 ["/api/", "/docs/getting-started/", "/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)
}
}
});
}());
//----------------------------------------->
我首先拆分所有字符串并将标题放入标题数组,然后删除重复项并相应地映射数据。
我只是觉得这是非常糟糕的代码,还有更好的方法我只是想不出来。
您可以创建一个 mapper
对象,它将输出中的对象映射到每个对象根中的 title
。 split
在 /
获取所有路径块。 .filter(Boolean)
删除从字符串开头和结尾创建的所有空字符串。如果只有一个匹配项,那么它属于默认的 null
对象。否则,使用 matches
中的第一个键作为累加器中的键。
const input = ["/api/", "/docs/getting-started/", "/docs/", "/plugin/", "/plugin/user/", "/plugin/profile/"];
const mapper = input.reduce((acc, path) => {
let matches = path.split(/\//).filter(Boolean),
mapperKey = null;
if (matches.length > 1)
mapperKey = matches[0];
if (!acc[mapperKey])
acc[mapperKey] = { title: mapperKey, pages: [] };
const title = matches.pop();
acc[mapperKey].pages.push({ title, path });
return acc;
}, {})
const output = Object.values(mapper);
console.log(output)