【问题标题】:Create string paths from nested object in Javascript从 Javascript 中的嵌套对象创建字符串路径
【发布时间】:2018-08-02 23:26:00
【问题描述】:

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

输入:

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

【问题讨论】:

  • 您的输出中的路径有时有斜杠 (/app/body/abs/),有时没有(/app/app/body)。您是否想要带有或不带有斜线的结果,或者是否有其他标准可以包含它?
  • 是的,抱歉,这是我的错误。我想要没有尾随斜杠。谢谢你的回答。

标签: javascript file object recursion nested


【解决方案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));

所以我保留了你的大部分代码,但改变了这样一个事实,即当你保留“旧”键时,我保留当前路径,它作为所有文件的前缀和所有目录的前缀将附加当前密钥。

【讨论】:

  • 谢谢 Sylwester,我知道我很接近,但我的逻辑有点不对劲。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-09
      • 2021-08-31
      • 1970-01-01
      • 1970-01-01
      • 2011-09-23
      相关资源
      最近更新 更多