【问题标题】:I need to traverse an object and return some values from it recursively我需要遍历一个对象并递归地从中返回一些值
【发布时间】:2019-01-30 15:26:54
【问题描述】:

当我将可选的第二个参数传递给“listFiles”时,我遇到了困难。我正在努力找出如何列出给定子目录中的文件。列出数据描述的文件系统的给定目录中的文件。因此,您应该能够从数据中返回文件列表。

参数:

data {Object} - 如上所述的文件系统对象

dirName {String} - 想要列出文件的目录名。

注意:此参数是可选的。如果未提供,请列出所有文件。

Returns {Array}目录dirName下的文件,包括子目录。

完成这个练习的方法应该是使用递归。我能够使用以下代码从文件系统对象返回所有文件:

const fileData = {
  dirName: 'app',
  files: ['index.html'],
  subDirs: [{
      dirName: 'js',
      files: [
        'main.js',
        'app.js',
        'misc.js',
      ],
      subDirs: [{
        dirName: 'vendor',
        files: [
          'jquery.js',
          'underscore.js',
        ],
        subDirs: [],
      }, ],
    },
    {
      dirName: 'css',
      files: [
        'reset.css',
        'main.css',
      ],
      subDirs: [],
    },
  ],
};

function listFiles(data, dirName) {

    let result = [];

    const traverseFileSystem = (obj) => {
      Object.keys(obj).forEach((key) => {
        if (obj[key] && typeof obj[key] === 'object') {
          if (key === 'files') {
            result = [...result, ...obj[key]];
          }
          traverseFileSystem(obj[key]);
        }
      });
    };

    traverseFileSystem(data);

    console.log(result);
  }

listFiles(fileData, 'js');

【问题讨论】:

    标签: javascript recursion traversal


    【解决方案1】:

    试试

    const trFS= dir=> dir.dirName==dirName ? dir : dir.subDirs.flatMap(d=> trFS(d));
    
    const trFSNoDir = dir => [...dir.subDirs.flatMap(d=> trFSNoDir(d)), ...dir.files];
    

    const fileData = {
      dirName: 'app',
      files: ['index.html'],
      subDirs: [{
          dirName: 'js',
          files: [
            'main.js',
            'app.js',
            'misc.js',
          ],
          subDirs: [{
            dirName: 'vendor',
            files: [
              'jquery.js',
              'underscore.js',
            ],
            subDirs: [],
          }, ],
        },
        {
          dirName: 'css',
          files: [
            'reset.css',
            'main.css',
          ],
          subDirs: [],
        },
      ],
    };
    
    function listFiles(data, dirName) {
    
        const trFS= dir=> dir.dirName==dirName ? dir : dir.subDirs.flatMap(d=> trFS(d));
        
        const trFSNoDir = dir => [...dir.subDirs.flatMap(d=> trFSNoDir(d)), ...dir.files];
        
        return dirName ? trFS(data)[0] : trFSNoDir(data);        
    }
    
    console.log("dir name: js\n", listFiles(fileData, 'js'));
    console.log("dir name: css\n", listFiles(fileData, 'css'));
    console.log("dir name: -\n",listFiles(fileData));

    当给定 dirName 时,我返回带有文件和子目录的对象(而不是数组),因为您没有指定输出数组的外观(例如,该数组中的子目录是否应该只是对象或名称) - 这个对象可以映射到数组的简单方法(例如,如果r 包含结果,则由[...r.files,...r.subDirs] )。

    【讨论】:

    • 不错的方法!谢谢。但我正在尝试返回所有文件,包括他们孩子中的文件。例如,当我传递 'js' 时,它也应该返回 'vendor' 中的文件。
    • 谢谢!真快!!
    【解决方案2】:

    完整的解决方案:

    function listFiles(data,dirName,level){
      var files=[];
      if(!level){
        level=0;
        data=[data];
      }
      for(var item of data){
        var subDirs=item.subDirs;
        if(subDirs && subDirs.length){
          files=files.concat(listFiles(subDirs,dirName,level+1));
        }
        if(dirName && item.dirName !== dirName){
          continue;
        }
        
        files.push(item);
       
      }
      return files;
    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-01
      • 2017-02-18
      • 1970-01-01
      • 1970-01-01
      • 2013-03-02
      • 2019-06-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多