疑念は探究の動機であり、探究の唯一の目的は信念の確定である。

数学・論理学・哲学・語学のことを書きたいと思います。どんなことでも何かコメントいただけるとうれしいです。特に、勉学のことで間違いなどあったらご指摘いただけると幸いです。 よろしくお願いします。くりぃむのラジオを聴くこととパワポケ2と日向坂46が人生の唯一の楽しみです。

【GAS】フォルダ配下にあるファイルを再帰的に探索する

概要
GAS(GoogleAppsScript)において、あるフォルダ配下のファイル(スプレッドシート)を再帰的に検索するプログラムを作成した。


フォルダ構成

myDrive
├── GoogleAppsScriptProject
└── folder
├── folder1
│   ├── folder1-1
│   │   ├── folder1-1-1
│   │   │   ├── folder1-1-1-1
│   │   │   ├── folder1-1-1-2
│   │   │   │   └── folder1-1-1-2-1
│   │   │   │   ├── spreadsheet1-1-1-2-1
│   │   │   │   └── spreadsheet1-1-1-2-1_2
│   │   │   ├── folder1-1-1-3
│   │   │   ├── spreadsheet1-1-1
│   │   │   ├── spreadsheet1-1-1_2
│   │   │   └── spreadsheet1-1-1_3
│   │   └── folder1-1-2
│   │   └── spreadsheet1-1-2
│   └── folder1-2
├── folder2
└── folder3
├── folder3-1
│   ├── folder3-1-1
│   │   ├── spreadsheet3-1-1
│   │   └── spreadsheet3-1-1_2
│   ├── folder3-1-2
│   ├── spreadsheet3-1
│   └── spreadsheet3-1_2
└── spreadsheet3

f:id:yoheiwatanabe0606:20210430232121p:plain


期待値
指定引数: folderのID
期待値:

  1. spreadsheet1-1-1-2-1
  2. spreadsheet1-1-1-2-1_2
  3. spreadsheet1-1-1
  4. spreadsheet1-1-1_2
  5. spreadsheet1-1-1_3
  6. spreadsheet1-1-2
  7. spreadsheet3-1-1
  8. spreadsheet3-1-1_2
  9. spreadsheet3-1
  10. spreadsheet3-1_2
  11. spreadsheet3


GoogleAppsScriptProject(GASのファイル名)

function myFunction() {
  // もしも指定フォルダがマイドライブ以外の場合 
  var folderId = 'myomyomyomyomyo_xxxxxx_id';

  // もしも指定フォルダがマイドライブの場合
  // var rootId = DriveApp.getRootFolder().getId();
  // folderId = rootId;

  var folderArr = [folderId];
  folderArr = searchRecursiveFolders(folderId, folderArr);

  var assoArr = {};
  for (var i = 0; i < folderArr.length; i++) {
    var folderId = folderArr[i];
    var fileIdList = existFile(folderId);
    if (fileIdList.length) {
      assoArr[folderId] = fileIdList;
    }
  }

  for (folderId in assoArr) {
    var folderName = DriveApp.getFolderById(folderId).getName();
    // デバッグ
    Logger.log('<------------ START ------------>');
    Logger.log('folderName: ' + folderName); // フォルダ名

    for (var i = 1; i < assoArr[folderId].length; i++) {
      var fileName = DriveApp.getFileById(assoArr[folderId][i]).getName();

      // デバッグ
      Logger.log('fileName: ' + fileName); // ファイル名
    }

    // デバッグ
    Logger.log('<------------ END ------------>');
  }
}

function searchRecursiveFolders(folderId, folderArr) {
  var folders = DriveApp.getFolderById(folderId).getFolders();  
  while (folders.hasNext()) {
    var folderId = folders.next().getId();
    folderArr.push(folderId);
    searchRecursiveFolders(folderId, folderArr);
  }

  return folderArr;
}

/************************************ */
function existFile(folderId) {
  var fileIdList = [];
  var folder = DriveApp.getFolderById(folderId);
  var fileIterator = folder.getFiles();
  while (fileIterator.hasNext()) {
      fileIdList[0] = true;
      // ファイルIDのオブジェクト取得
      var fileId = fileIterator.next().getId();
      fileIdList.push(fileId);
  }

  return fileIdList;
}


実行結果
f:id:yoheiwatanabe0606:20210430224218p:plainf:id:yoheiwatanabe0606:20210430224221p:plainf:id:yoheiwatanabe0606:20210430224225p:plain


前提/改善点

  • GASでHello, World!ができる人
  • JavaScriptができる人ならば、もう少しスマートに書けると思う(fileIdList[0] = true;とか。Pythonのように実装したらうまくいかなかったため、このようなへんてこりんなコードで妥協した)

僕から以上