代码之家  ›  专栏  ›  技术社区  ›  totalnoob

从一个javascript对象递归地创建一个url数组

  •  2
  • totalnoob  · 技术社区  · 7 年前

    带着物体

    { 
        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 回复  |  直到 7 年前
        1
  •  4
  •   Jonas Wilms    7 年前

    我会用发电机的:

     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: { /*...*/ } })]);
    
        2
  •  1
  •   ggorlen Hoàng Huy Khánh    7 年前

    这里有一个简单的递归方法,可以避免添加任何 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
          }
        }
      })
    );
        3
  •  1
  •   Nina Scholz    7 年前

    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);