首页 > 解决方案 > How to build a menu list object recursively in JavaScript?

问题描述

With an array of

['/social/swipes/women', '/social/swipes/men', '/upgrade/premium'];

I'd like to construct an map object that looks like:

{
    'social': {
        swipes: {
            women: null,
            men: null
        }
    },
    'upgrade': {
        premium: null
    }
}

const menu = ['/social/swipes/women', '/social/likes/men', '/upgrade/premium'];
const map = {};

const addLabelToMap = (root, label) => {
  if(!map[root]) map[root] = {};
  if(!map[root][label]) map[root][label] = {};
}

const buildMenuMap = menu => {
  menu
    // make a copy of menu
    // .slice returns a copy of the original array
    .slice()
    // convert the string to an array by splitting the /'s
    // remove the first one as it's empty
    // .map returns a new array
    .map(item => item.split('/').splice(1))
    // iterate through each array and its elements
    .forEach((element) => {
      let root = map[element[0]] || "";

      for (let i = 1; i < element.length; i++) {
        const label = element[i];
        addLabelToMap(root, label)
        // set root to [root][label]
        //root = ?
        root = root[label];
      }
    });
}

buildMenuMap(menu);

console.log(map);

But I'm unsure how to switch the value of root.

What do I set root to so that it recursively calls addLabelToMap with

'[social]', 'swipes' => '[social][swipes]', 'women' => '[social][swipes]', 'men'?

I've used root = root[element] but it's giving an error.

Alternative solutions would be great, but I'd like to understand why this isn't working fundamentally.

标签: javascriptarraysecmascript-6javascript-objectsarrow-functions

解决方案


这个问题是关于创建对象并维护它的状态,同时循环遍历input数组和基于/.

这可以使用Array.reduce我们从空对象开始的地方来完成,在循环input中我们开始填充它,并且对于每个字符串中的最后一个单词,我们将值分配null给对象属性。

let input = ['/social/swipes/women', '/social/swipes/men', '/upgrade/premium'];

let output = input.reduce((o, d) => {
  let keys = d.split('/').filter(d => d)
  
  keys.reduce((k, v, i) => {
    k[v] = (i != keys.length - 1)
             ? k[v] || {} 
             : null
    
    return k[v]
  }, o)
  
  return o
}, {})

console.log(output)


推荐阅读