2010-08-04 18 views
8

Nella mia app, sto filtrando una gamma di file da vari tipi, come il seguente:metodo Scala che restituisce più funzioni di filtro concatenate

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")) 

Ma sarebbe più ordinatamente per definire un metodo che prende un Array di stringhe e restituisce tutti questi filtri come una funzione concatenata. È possibile? Quindi che posso scrivere

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

risposta

10

Si potrebbe fare qualcosa di simile:

def notEndsWith(suffix: String*): File => Boolean = { file => 
    !suffix.exists(file.getName.endsWith) 
} 
+1

+1 è il motivo per cui amo Scala – onof

+3

Bello, anche se probabilmente implementerei "endsWith" piuttosto che "notEndsWith", come regola. Se implementi "notEndsWith" e hai effettivamente bisogno di "endsWith", finirai per codificare come! NotEndsWith, che è fonte di confusione a causa del doppio negativo. Definire sempre le condizioni positivamente è più importante con la programmazione funzionale, perché la densità aggiuntiva dei costrutti funzionali richiede un'attenzione ulteriore alla chiarezza di espressione –

1

Un modo potrebbe essere qualcosa di simile:

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

che potrebbe essere chiamato in questo modo:

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