Scala 列表包含对象=>;对象

Scala 列表包含对象=>;对象,scala,Scala,您好,目前我尝试查看列表是否包含元素。当前列表包含一个对象,该对象包含另一个应检查的对象 这两个列表包含以下类: case class SourceFile(name: String, path: String, date_changed: java.util.Date) case class DBSourceFile(id: UUID, file: SourceFile) 所以我有两个列表list1:List[SourceFile]和list2:List[DBSourceFile] 目前,我

您好,目前我尝试查看列表是否包含元素。当前列表包含一个对象,该对象包含另一个应检查的对象

这两个列表包含以下类:

case class SourceFile(name: String, path: String, date_changed: java.util.Date)
case class DBSourceFile(id: UUID, file: SourceFile)
所以我有两个列表list1:
List[SourceFile]
和list2:
List[DBSourceFile]
目前,我使用foreach循环来访问列表1中的源文件:

for(file <- files)
当我使用contains时

首选的方法是什么

我当时就是这样做的:

def checkExistingFilesInDB() {
  for(diskFile <- diskFiles) {
    val dbFile = dbFiles.filter(dbFile => dbFile.file.name == diskFile.name && dbFile.file.path == diskFile.path)
    if(dbFile.length == 1) {
      //println(dbFile(0))
      if(!(diskFile == dbFile(0).file)) {
        Logger.info("File updated: " + dbFile(0) + " \nwith: " + diskFile)
        SourceFile.update(DBSourceFile(dbFile(0).id, diskFile))  
      }
    }
    else if (dbFile.length == 0) { 
      SourceFile.createSourceFile(diskFile)
      Logger.info("File inserted into Database: " + diskFile)
    }
    else {
      // TODO: What happens if more than 1 reference of the file is in the database
      Logger.error("File exists two times on the database")
    } 
  }
}
def checkExistingFilesInDB(){
for(diskFile.dbFile.name==diskFile.name&&dbFile.file.path==diskFile.path)
if(dbFile.length==1){
//println(dbFile(0))
如果(!(diskFile==dbFile(0.file)){
Logger.info(“文件更新:”+dbFile(0)+“\n带:”+diskFile)
更新(DBSourceFile(dbFile(0.id,diskFile))
}
}
如果(dbFile.length==0){
SourceFile.createSourceFile(磁盘文件)
Logger.info(“插入数据库的文件:”+diskFile)
}
否则{
//TODO:如果数据库中有多个文件引用,会发生什么情况
error(“文件在数据库中存在两次”)
} 
}
}

准确地说,你是如何使用这张支票的?通常,existscontains的使用方式非常笨拙,您可以使用更惯用的Scala完全消除它们

例如,您的问题暗示您正在做类似的事情:

dbFiles.count(dbFile => dbFile.file.name == diskFile.name && dbFile.file.path == diskFile.path)
val fileCheck = { dbFile: SourceFile => dbFile.name == diskFile.name && dbFile.path == diskFile.path }
if (list1 exists fileCheck ) {
  var Files = list1 filter fileCheck
  for (file <- Files) {
    // Do something with file
  }
}
val fileCheck = { dbFile: SourceFile => dbFile.name == diskFile.name && dbFile.path == diskFile.path }
if (list1 exists fileCheck ) {
  val Files = list1 filter fileCheck
  for (file <- Files) {
    // Do something with file
  }
} else {
  // Meh! No matching files.
}
这是很好的和简单的,将符合每一种情况。但是克里斯蒂安,考虑一下:如果你有多个DB记录,所有的名字和路径都是相同的,并且有一个真实的文件是对应的,那么你所需要做的就是保留这些记录中的一个并更新它,同时删除其他的记录。让我向您展示如何使用match

dbFile match {
  case Nil => // Empty list, insert file into db
  case first :: others => { // At least one match
    for (errorFile <- others) {
      SourceFile.delete(errorFile.id) // Assuming you have this or similar method
    }
    SourceFile.update(DBSourceFile(first.id, diskFile))
  }
}
dbFile匹配{
case Nil=>//空列表,将文件插入数据库
案例优先::其他=>{//至少有一个匹配项

对于(errorFile听起来像你想要
存在
如果某个东西在列表中存在两次会发生什么?
存在
将在确定至少有一个匹配项时返回true。啊,okai,是的,这对我来说已经足够了。ty.目前我用过滤器更新了所有内容,而不是存在,我的代码看起来像你的最后一个片段或几乎像你的l我只是检查过滤器是否给我一个包含0、1或更多元素的列表,如果我有更多元素,它会给出一个exception@ChristianSchmitt我不确定你是不是告诉我你尝试了这个,但是你得到了一个意外的异常,或者你的代码设计成当有两个以上的元素时抛出一个异常。不,我只是说我像y一样实现了它我们的代码片段,只做了一个小小的更改,我有一个if-else,它查找筛选列表的列表长度。如果筛选列表有1个元素,它会做一些事情如果列表有0个元素,它会做一些事情,如果列表有多个元素,它会抛出一个异常。如果我写了idomatic scala,我仍然感觉很糟糕。我更新了我的问题使用我的新代码。@ChristianSchmitt啊,我看到你更新了你的问题。好的,等我有时间的时候,我会带着更多的建议回来。更新了答案。保留原始的、一般性的建议,并添加符合你实际代码的具体想法。
val files = for (file <- list1 if file.name == diskFile.name && file.path == diskFile.path) yield file
val dbFile = dbFiles.filter(dbFile => dbFile.file.name == diskFile.name && dbFile.file.path == diskFile.path
dbFiles.length match {
  case 0 => //Insert file into db
  case 1 => //Update existing db record
  case _ => //Must be more than one!  Aroogah!  Aroogah!
}
dbFile match {
  case Nil => // Empty list, insert file into db
  case first :: others => { // At least one match
    for (errorFile <- others) {
      SourceFile.delete(errorFile.id) // Assuming you have this or similar method
    }
    SourceFile.update(DBSourceFile(first.id, diskFile))
  }
}