递归地从对象创建网址数组-javascript

时间:2018-11-27 16:12:52

标签: javascript recursion

我已经找到了如何基于数组创建对象的方法,现在我正试图了解如何从该对象重新构建数组。

与对象

{ 
    social: { 
        children: { 
            swipes: {
                children: {
                    women: null,
                    men: null
                }
            } 
        } 
    },

    upgrade: { 
        children: { 
            premium: null 
        } 
    } 
 }

如何创建

的数组
['/social/swipes/women', '/social/swipes/men', '/upgrade/premium']

到目前为止,我已经编写了一个遍历对象的函数

let iterate = obj => {
  const urls = [];

  for (let k in obj) {
    if (obj[k] !== null && obj[k].hasOwnProperty('children')) {
      console.log('iterating through key: ', k)
      iterate(obj[k].children)
    } else {
      console.log(k, 'is null')
    }
  }
}

3 个答案:

答案 0 :(得分:4)

为此,我将使用一个生成器:

 function* paths(obj, previous = "") {
   for(const [key, value] of Object.entries(obj)) {
     if(typeof value === "object" && value !== null) {
       yield* paths(value.children, previous + "/" + key);
     } else {
       yield previous + "/" + key;
    }
  }
}

可以称为:

 console.log([...paths({ social: { /*...*/ } })]);

答案 1 :(得分:1)

您可以通过收集所有键,然后构建联接的字符串来采取迭代和递归的方法。

function getKeys(object) {
    return Object
        .entries(object)
        .reduce((r, [k, v]) =>
            r.concat(v && typeof v === 'object' && v.children
                ? getKeys(v.children).map(sub => [k].concat(sub))
                : k
            ),
            []
        );
}

var data = { social: { children: { swipes: { children: { women: null, men: null } } } }, upgrade: { children: { premium: null } } },
    result = getKeys(data).map(a => a.join('/'));

console.log(result);

与生成器相同,并且没有用于收集数组的第二个参数的签名。

function* getKeys(object) {
    var k;
    for ([k, v] of Object.entries(object)) {
        if (v && typeof v === 'object' && v.children) {
            yield* Array.from(getKeys(v.children), sub => [k].concat(sub));
        } else {
            yield [k];
        }
    }
}

var data = { social: { children: { swipes: { children: { women: null, men: null } } } }, upgrade: { children: { premium: null } } },
    result = Array.from(getKeys(data), a => a.join('/'));

console.log(result);

答案 2 :(得分:1)

这是一种简单的递归方法,可避免在路径中添加任何children键:

const pathify = (data, path = "", res = []) => {
  Object.keys(data).forEach(k => {
    if (data[k] === null) {
      res.push(`${path}/${k}`);
    } 
    else {
      pathify(data[k], path + (k === "children" ? "" : `/${k}`), res);
    }
  });

  return res;
};

console.log(
  pathify({
    social: {
      children: {
        swipes: {
          children: {
            women: null,
            men: null
          }
        }
      }
    },
    upgrade: {
      children: {
        premium: null
      }
    }
  })
);