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

3
我将尝试将表示文件系统的嵌套对象转换为字符串数组,以表示每个文件夹和文件的文件路径。
输入:
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);

2
你的输出路径有时带有尾随斜杠 (/app/body/abs/),有时没有 (/app/app/body)。您想要结果带有还是不带该斜杠,或者是否有其他标准来包含或排除它? - CRice
是的,抱歉,这是我的错误。我想要没有尾随斜杠。谢谢你的回答。 - Philip-lf
3个回答

3
以下是一份可运行的版本:

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

所以我保留了你的大部分代码,但改变了一个事实,即你保留了“旧”密钥,而我保留了当前路径,并将其作为所有文件的前缀,也是将当前密钥附加到所有目录的前缀。


谢谢Sylwester,我知道我很接近了,但我的逻辑有点偏差。 - Philip-lf

1

你在使用递归的道路上是正确的。对于每个调用,循环遍历当前对象中的所有属性,为属性创建路径并将其添加到结果数组中。如果属性键指向一个对象,则它是一个非终端节点,并被递归调用以添加其子节点的路径。

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

    if (typeof o[dir] === "object") {
      pathify(o[dir], res, path.concat(dir));
    }
  }

  return res;
};

const 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
    }
  }
};

console.log(pathify(obj));


1
这是一种利用 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))


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接