【问题标题】:Convert string into nested objects and arrays将字符串转换为嵌套对象和数组
【发布时间】:2020-03-23 20:19:01
【问题描述】:

我在一个项目中,前一个人做了一些奇怪的路由,基本上我从内容丰富的字符串中得到了 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)
                }
            }
        });
    }());
    //----------------------------------------->

我首先拆分所有字符串并将标题放入标题数组中,然后删除重复项并相应地映射数据。

我只是觉得这是一个非常糟糕的代码,还有更好的方法我只是想不通。

【问题讨论】:

  • 嗨,我认为这是您提出问题的错误地方。这更像是一个与代码审查相关的问题。在这里,我们询问一些可能对其他人也有帮助的特定主题。在这里试试:codereview.stackexchange.com

标签: javascript arrays object contentful


【解决方案1】:

您可以创建一个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)

【讨论】:

  • 谢谢,它有效,我不知道如何,但我会研究它。干杯!
  • @Jaykch 的想法是在输出数组和映射器对象的值中使用相同的对象。例如,创建了一个像pluginObject = { title: "plugin", pages: [..] } 这样的对象。在mapper["plugin"] = pluginObjectoutput.push(pluginObject ) 中使用了相同的对象引用。因此,如果您找到以“plugin”开头的路径,您只需将其推送到mapper["plugin"].pages 数组。这也将更新输出数组中的对象,因为它们都指向同一个对象。您不必遍历数组并检查是否有带有title: "plugin"的对象
  • 我已将其更新为使用reduce 并简化正则表达式以使用拆分
  • 谢谢,我现在看了,很奇怪,我以为我无法在javascript中找到array[key]。现在看起来好傻。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2023-03-12
  • 2014-03-16
  • 1970-01-01
  • 2021-11-21
  • 2019-04-15
  • 1970-01-01
  • 1970-01-01
  • 2021-02-21
相关资源
最近更新 更多