2017-07-24 7 views
0

Ich habe ein Array wie:Scala Filterelemente in Seq/Array zwischen Separatoren

val array = Array("Hello", "```", "blabla", "anything", "filler", "```", "another filler") 

Die filter Methode nur auf jedem Element des Arrays oder Seq

ist
array.filter(s => !s.startsWith("```")) 
> Array(Hello, blabla, anything, filler, another filler) 

Ich möchte, entfernen alles zwischen den Separatoren "```". Das Endergebnis wird

Array("Hello", "another filler") 

sein Das Problem ist ähnlich wie Bracket coding task solved by a Stack. Wie konnten Sie das in reinem FP erreichen?

Weitere

Es gibt 2 Abschnitte durch den Separator begrenzt "```".

Hinweis: Das Trennzeichen ist nicht gleich, sondern beginnt mit "```". Es gibt eine "```scala"

val input = Array("Hello", "```", "blabla1", "```", "blabla2", "```scala","blabla3", "filler", "```", "blabla4") 

filteredOutput = Array("Hello", "blabla2", "blabla4") 

PS: Vielleicht heraus Sie die Lösung filtert aus einer Abschlags-Datei den Code Kommentar aus.

+0

Was passiert, wenn Sie eine ungerade Anzahl von ' "'' '" '? Den letzten behalten? –

+0

Ja, behalte die letzte. Für ungerade Anzahl von '' '' '' ', wird das letzte Trennzeichen" '' '" in der Ausgabe sein. –

Antwort

2

Dies sollte Ihre aktualisierten Anforderungen erfüllen.

def condense(ss: Seq[String], delimiter: String): Seq[String] = { 
    val start = ss.indexWhere(_.startsWith(delimiter)) 
    val stop = ss.indexWhere(_.startsWith(delimiter), start + 1) 
    if (stop < 0) ss 
    else condense(ss.patch(start, Seq(), stop-start+1), delimiter) 
} 

condense(input, "```") // res0: Array[String] = Array(Hello, blabla2, blabla4) 
1

Ich bin nicht sicher, ob dies unbedingt der beste Weg ist, aber eine Art und Weise kam ich mit ist es zu falten:

val (filteredOutput: Array[String], _) = 
    input.foldLeft((Array[String](), true)) { 
    case ((output: Array[String], include: Boolean), sep) if sep.startsWith("```") => (output, !include) 
    case ((output: Array[String], true), next: String) => (output :+ next, true) 
    case ((output: Array[String], false), _) => (output, false) 
    } 

Hier ist eine aktualisierte Version, die Ihre aktualisierte Anforderung in Bezug auf ungerade behandeln sollte Anzahl der Separatoren:

val filteredOutput = { 
    val (workingOutput: Array[String], _, discard: List[String]) = 
    input.foldLeft((Array[String](), true, List[String]())) { 
     case ((output: Array[String], include: Boolean, _), sep) if sep.startsWith("```") => 
     (output, !include, if (include) List(sep) else Nil) 

     case ((output: Array[String], true, _), next: String) => 
     (output :+ next, true, Nil) 
     case ((output: Array[String], false, discard: List[String]), next: String) => 
     (output, false, next :: discard) 
    } 
    workingOutput ++ discard.reverse 
} 
+0

es funktioniert. Vielen Dank –

+0

Ich habe einen kleinen Schnitt im Abschnitt Weiter gemacht. Das Trennzeichen beginnt mit "' '' ", es ist nicht gleich. –

+0

Ich habe es aktualisiert, um anzuzeigen, dass Trennzeichen mit "' '' "beginnen. Es erfüllt jedoch nicht Ihre neue Anforderung für eine ungerade Anzahl von Separatoren. –

1

Eine andere Version, die Verwendung von Indizes zu vermeiden:

val input = Array("Hello", "```", "blabla1", "```", 
        "blabla2", "```scala", "blabla3", "filler", "```", "blabla4") 

def condense(xs: Array[String], acc: Array[String] = Array()): Array[String] = { 
    if (xs.isEmpty) acc 
    else { 
    val (before, after) = xs.span(!_.startsWith("```")) 
    val remaining = after.drop(1).dropWhile(!_.startsWith("```")) 
    if (remaining.isEmpty) // unclosed commment 
     acC++ xs 
    else condense(remaining.drop(1), acC++ before) 
    } 
} 

condense(input) //> res0: Array[String] = Array(Hello, blabla2, blabla4) 
+1

Schön, aber Sie haben die zusätzliche Anforderung (in den Kommentaren der Frage erwähnt) verpasst: "Für die ungerade Anzahl von' '' '' '' wird das letzte Trennzeichen '' '' '' in der Ausgabe sein. " – jwvh

+0

Blech. Ja, diesen Kommentar habe ich verpasst. Fest. –

Verwandte Themen