views:

96

answers:

2

In my app, I'm filtering a file array by various types, like the following:

val files:Array[File] = recursiveListFiles(file)
  .filter(!_.toString.endsWith("png"))
  .filter(!_.toString.endsWith("gif"))
  .filter(!_.toString.endsWith("jpg"))
  .filter(!_.toString.endsWith("jpeg"))
  .filter(!_.toString.endsWith("bmp"))
  .filter(!_.toString.endsWith("db"))

But it would be more neatly to define a method which takes a String array and returns all those filters as a concatenated function. Is that possible? So that I can write

val files:Array[File] = recursiveListFiles(file).filter(
  notEndsWith("png", "gif", "jpg", "jpeg", "bmp", "db") 
)
+9  A: 

You could do something like this:

def notEndsWith(suffix: String*): File => Boolean = { file =>
  !suffix.exists(file.getName.endsWith)
}
Moritz
+1 it's the reason I love Scala
onof
Nice, although I would probably implement "endsWith" rather than "notEndsWith", as a rule. If you implement "notEndsWith" and actually need "endsWith", you end up coding as !notEndsWith, which is confusing because of the double negative. Always defining conditions positively is more important with functional programming, because the extra density of functional constructs demands extra attention to clarity of expression
Dave Griffith
+1  A: 

One way would be something like this:

def notEndsWith(files:Array[File], exts:String*) = 
  for(file <- files; if !exts.exists(file.toString.endsWith(_))) yield file

Which could be called like this:

val files = Array(new File("a.png"),new File("a.txt"),new File("a.jpg"))
val filtered = notEndsWith(files, "png", "jpg").toList
Fabian Steeg