【GAS】指定フォルダの配下全てのフォルダ、ファイルを取得するクラス

指定フォルダ配下の全てのフォルダ、ファイルを取得するコードを書きました。


```js:main
function main() {

  const url = ''; //フォルダのURL
  const data = new GetFolderData(url);
  data .getFolders();

  console.log(data);
  /*
  { unprocessedFolderIds: [],
  folders: [ {} ],
  files: [ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {} ] }
   */
}
```
unprocessedFolderIdsは未処理のフォルダが溜まる場所として
用意しているので、必ず空の配列になります。

上記実行内容だと指定したフォルダのURLの配下には
1つのフォルダと12のファイルが存在したということです。

クラスのコードは下記です。

```js:Class
class GetFolderData {
  constructor(url) {
    this.unprocessedFolderIds = [url.match(/(?<=folders\/).*/)];
    this.folders = [];
    this.files = [];
  }
  
  /**
   * ① unprocessedFolderIdsからフォルダIDを取得
   * ② ①のフォルダに存在するフォルダをfoldersに格納
   * ③ ①のフォルダに存在するフォルダIDをunprocessedFolderIdsに格納
   * ④ ①のファイルを取得するgetFilesの実行
   */
  getFolders() {
    const folderId = this.unprocessedFolderIds.shift();
    const folder = DriveApp.getFolderById(folderId);
    const folders = folder.getFolders();

    while (folders.hasNext()) {
      const folder = folders.next();
      this.folders.push(folder);
      this.unprocessedFolderIds.push(folder.getId());
    }

    this.getFiles(folder);
  }

  /**
   * ① 受け取ったフォルダないのファイルをfilesに格納
   * ② unprocessedFolderIdsが存在すればgetFolders実行
   * ③ unprocessedFolderIdsが存在しない場合は集めたファイル、フォルダの処理に移行
   * 
   * @param {Object} フォルダ
   */

  getFiles(folder) {
    const files = folder.getFiles();

    while (files.hasNext()) {
      this.files.push(files.next());
    }

    // 未処理のフォルダがなけばprocess()を実行
    if (this.unprocessedFolderIds[0]) {
      this.getFolders();
    } else {
      this.process();
    }
  }

  process() {
    // 集めたフォルダ、ファイルで処理したい内容
  }
}
```

## 更新順に並び替えて出力

並び替えの方法は下記の記事を参考にしました。
https://www.webprofessional.jp/sort-an-array-of-objects-in-javascript/

元のデータにprocessで処理を追加しました。

```js:Class(ファイルの並び替え実施)
class GetFolderData {
  constructor(url) {
    this.unprocessedFolderIds = [url.match(/(?<=folders\/).*/)];
    this.folders = [];
    this.files = [];
  }
  
  /**
   * ① unprocessedFolderIdsからフォルダIDを取得
   * ② ①のフォルダに存在するフォルダをfoldersに格納
   * ③ ①のフォルダに存在するフォルダIDをunprocessedFolderIdsに格納
   * ④ ①のファイルを取得するgetFilesの実行
   */
  getFolders() {
    const folderId = this.unprocessedFolderIds.shift();
    const folder = DriveApp.getFolderById(folderId);
    const folders = folder.getFolders();

    while (folders.hasNext()) {
      const folder = folders.next();
      this.folders.push(folder);
      this.unprocessedFolderIds.push(folder.getId());
    }

    this.getFiles(folder);
  }

  /**
   * ① 受け取ったフォルダないのファイルをfilesに格納
   * ② unprocessedFolderIdsが存在すればgetFolders実行
   * ③ unprocessedFolderIdsが存在しない場合は集めたファイル、フォルダの処理に移行
   * 
   * @param {Object} フォルダ
   */

  getFiles(folder) {
    const files = folder.getFiles();

    while (files.hasNext()) {
      this.files.push(files.next());
    }

    // 未処理のフォルダがなけばprocess()を実行
    if (this.unprocessedFolderIds[0]) {
      this.getFolders();
    } else {
      this.process();
    }
  }
  

  /**
   * アップデート日が新しい順になるほうに変更
   */
  process() {
    this.ary = [];
    for (const file of this.files) {
      const obj = {};
      obj['date'] = Utilities.formatDate(file.getLastUpdated(), 'JST', 'yyyy-MM-dd');
      obj['title']= file.getName();
      this.ary.push(obj);
    }

    this.ary.sort(function(a, b) {
      if (a.date > b.date) {
          return -1;
      } else {
          return 1;
      }
    })
  }
}
```

```js:main
function main() {

  let url = '';
  const data = new GetFolderData(url);
  data.getFolders();

  console.log(data.ary);
}
```

並び替えをした配列を取得するためには
this.aryで作成したデータを取得すれば扱うことが可能です。