Мне нужно пройти объект и вернуть некоторые значения из него рекурсивно - PullRequest
0 голосов
/ 30 января 2019

Я застреваю, когда передаю необязательный второй параметр в 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');

Ответы [ 2 ]

0 голосов
/ 30 января 2019

Полное решение:

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;
}
0 голосов
/ 30 января 2019

попробуй

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]).

...