Scala method that returns multiple concatenated filter functions
Asked Answered
D

2

8

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") 
)
Dishonorable answered 4/8, 2010 at 22:4 Comment(0)
O
10

You could do something like this:

def notEndsWith(suffix: String*): File => Boolean = { file =>
  !suffix.exists(file.getName.endsWith)
}
Orontes answered 4/8, 2010 at 22:16 Comment(1)
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 expressionMeleager
A
1

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
Agent answered 4/8, 2010 at 22:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.