从Javascript中的嵌套对象创建字符串路径

时间:2018-08-02 23:26:00

标签: javascript file object recursion nested

我正在尝试将代表我的文件系统的嵌套对象转换为代表每个文件夹和文件的文件路径的字符串数组。

输入:

let obj = {
  'app': {
    'body': {
      'abs': {
        'muscles.txt': 1
      },
      'foot.js': 1,
      'hand.txt': 1,
      'leg.txt': 1
    },
    'cat.txt': 1,
    'dog.js': 1,
    'writing': {
      'pen.txt': 1,
      'phone.txt': 1
    }
  }
};

输出:

  [
  '/app', 
  '/app/body',
  '/app/body/abs/',
  '/app/body/abs/muscles.txt',
  '/app/body/foot.js',
  '/app/body/hand.txt',
  ...
]

到目前为止,我所拥有的(不起作用):

function filePaths(obj, oldKey = '', store = []) {
  for (let key in obj) {
    if (typeof obj[key] === 'object') {
      store.push('/' + key);
      filePaths(obj[key], key, store);
    } else {
      store.push('/' + oldKey + '/' + key);
    }
  }
  return store;
}

filePaths(obj);

3 个答案:

答案 0 :(得分:1)

这是一个有效的版本:

let obj = {
  'app': {
    'body': {
      'abs': {
        'muscles.txt': 1
      },
      'foot.js': 1,
      'hand.txt': 1,
      'leg.txt': 1
    },
    'cat.txt': 1,
    'dog.js': 1,
    'writing': {
      'pen.txt': 1,
      'phone.txt': 1
    }
  }
};

function filePaths(obj, prefix = '', store = []) {
  for (let key in obj) {
    const curPath = `${prefix}/${key}`;
    if (typeof obj[key] === 'object') {
      store.push(curPath);      
      filePaths(obj[key], curPath, store);
    } else {
      store.push(curPath);      
    }
  }
  return store;
}

console.log(filePaths(obj));

因此,我保留了大多数代码,但改变了一个事实,即在您保留“旧”键的同时,我保留了当前路径,它用作所有文件的前缀和所有目录的前缀将会附加当前密钥。

答案 1 :(得分:0)

这是递归的解决方案:

let obj = {
  'app': {
    'body': {
      'abs': {
        'muscles.txt': 1
      },
      'foot.js': 1,
      'hand.txt': 1,
      'leg.txt': 1
    },
    'cat.txt': 1,
    'dog.js': 1,
    'writing': {
      'pen.txt': 1,
      'phone.txt': 1
    }
  }
};

const pathify = (o, res=[], path=[]) => {
  for (const prop in o) {
    const s = path.join("/");
    res.push(`/${s ? `${s}/${prop}` : prop}`);

    if (o[prop] !== 1) {
      pathify(o[prop], res, path.concat(prop));
    }
  }

  return res;
};

console.log(pathify(obj));

说明

遍历对象中的每个属性,并为其创建路径并将其添加到结果数组。如果该属性的键的值不是1,则它是一个非终端节点,并被递归调用以为其子级添加路径。

答案 2 :(得分:0)

这是一种递归解决方案,它利用Object.keys方法和传播运算符concatmap来利用:

let obj = {
  'app': {
    'body': {
      'abs': {
        'muscles.txt': 1
      },
      'foot.js': 1,
      'hand.txt': 1,
      'leg.txt': 1
    },
    'cat.txt': 1,
    'dog.js': 1,
    'writing': {
      'pen.txt': 1,
      'phone.txt': 1
    }
  }
};

function filePaths(obj, prefix = "", store = []) {
  if (typeof obj !== "object") return [prefix];
  return (prefix && [prefix] || []).concat(...Object.keys(obj).map(k => filePaths(obj[k], prefix + "/" + k, store)))
}

console.log(filePaths(obj))