Google云端硬盘:用于计算节点具有多个父节点的FS的面包屑的算法

时间:2017-03-29 18:21:32

标签: javascript java algorithm scala google-drive-api

我目前正在使用Google Drive API,我需要在我的应用中显示Google云端硬盘文件的痕迹。 Google云端硬盘不是一个简单的树,并且具有文件/文件夹可能包含多个父项的特殊性。 Google云端硬盘没有面包屑的概念,因此获取面包屑(实际上是潜在的面包屑列表)的唯一方法是递归父母列表。

我目前能够计算Scala中所有潜在面包屑的列表:

type GoogleDriveBreadcrumb = List[GoogleDriveFile]

def getAllBreadcrumbs(fileId: String): Try[List[GoogleDriveBreadcrumb]] = Try {

  def getBreadcrumbsRecursive(currentFileId: String): List[GoogleDriveBreadcrumb] = {
    val file = fetchDriveFile(currentFileId)
    file.parentIds.flatMap { parentId =>
      getBreadcrumbsRecursive(parentId)
        .map(parentBreadcrumb => file :: parentBreadcrumb)
    }
  }

  getBreadcrumbsRecursive(fileId)
}

这样可以正常工作,但可能非常昂贵而且实际上并不可用,因为:

  • 我实际上并不需要所有的面包屑,我需要最合适的面包屑,因为我知道计算面包屑的“上下文”。我希望能够为此方法提供rootFolderId参数,以便它只返回一个面包屑(具有rootFolderId作为父级的那个),并且此面包屑将在该级别被截断rootFolderId表示返回的面包屑不应包含rootFolderId的父项。如果在任何面包屑中找不到rootFolderId,则该方法只能返回当前文件
  • 它将始终计算所有情况下的所有面包屑。我希望计算是懒惰的,并且一旦找到包含rootFolderId的面包屑就停止。

我希望我的方法有这个签名:

def getBreadcrumb(fileId: String,rootFolderId: String): Try[Option[GoogleDriveBreadcrumb]]

现在让我们假设我有一个驱动文件系统File有3个潜在的面包屑:

File < Folder1 < Folder2 < Folder3
File < Folder4 < Folder5 < Folder6
File < Folder7 < Folder8 < Folder9
  • getBreadcrumb(file,folder5Id)应该返回File < Folder4 < Folder5
  • getBreadcrumb(file,folder7Id)应该返回File < Folder7
  • getBreadcrumb(file,badFolderId)应该返回File

关于如何重新编写算法以实现此目标的任何想法,以便算法也有效(一旦找到正确的面包屑就停止)

由于

我用Scala,Java,Javascript标记这个问题,因为这些是我习惯的语言。我更喜欢基于Scala的实现,但只要我能理解解决方案,我就会对其他语言开放。

1 个答案:

答案 0 :(得分:0)

您可以尝试从文件开始,然后转到根文件夹。

如果您使用的是v2,那么您将重复循环,直到isRoot变为真:

文件结果:

 "parents": [
  {
   "kind": "drive#parentReference",
   "id": "FILEID",
   ........................
   "isRoot": false
  }
 ]

根结果:

 "parents": [
  {
   "kind": "drive#parentReference",
   "id": "FILEID",
   ........................
   "isRoot": true
  }
 ]

如果您使用的是v3:

如果您使用的是v3,那么您将重复查询循环,直到parents变为 null 或者响应不包含父对象。

文件结果:

{
 "id": "FILEID",
 "parents": [
  "PARENTID"
 ]
}

根结果:

{
 "id": "ROOTID"
}

您还可以查看Google Apps Script tutorial如何将其列为文件树(但在您的情况下只是从文件到根目录的路径)

希望这有帮助。