2016-04-25 11 views
0

Ich habe eine Liste von Strings, wie unten dargestellt, die mit jedem verbundenen Früchte und die Kosten auflistet. Im Falle von No-Wert wird angenommen, 5 sein:Split-String mit Standardwert in scala

val stringList: List[String] = List("apples 20", "oranges", "pears 10") 

Jetzt habe ich die Zeichenfolge zu erhalten Tupeln der Frucht und die Kosten geteilt werden soll. Wie ist das möglich?

stringList.map(query => query.split(" ")) 

ist nicht was ich will.

I found this, die ähnlich ist. Was ist die korrekte Art und Weise, dies zu tun?

+0

Ordnen Sie eine benutzerdefinierte Funktion zu, die sich aufteilt, und fügt dann ein Element hinzu, wenn das zweite fehlt. – JulienD

Antwort

3

Sie können einen regulären Ausdruck und Mustererkennung verwenden:

val Pat = """(.+)\s(\d+)""".r // word followed by whitespace followed by number 

def extract(in: String): (String, Int) = in match { 
    case Pat(name, price) => (name, price.toInt) 
    case _    => (in, 5) 
} 

val stringList: List[String] = List("apples 20", "oranges", "pears 10") 

stringList.map(extract) // List((apples,20), (oranges,5), (pears,10)) 

Sie haben zwei einfangende Gruppen im Muster. Diese werden als Strings extrahiert, also müssen Sie explizit mit .toInt konvertieren.

+0

Hier ist ein wenig über Mustervergleich: https://stackoverflow.com/questions/4636610/how-to-pattern-match-using-regular-expression-in-scala –

+2

'val r = """ (\ S +) \ s * (\ d +)? "" ". r; def f (s: String) = s Übereinstimmung {case r (n, null) => (n, 42) case r (n, i) => (n, i.toInt) case _ => (0,0) } 'um die Handhabung der leeren zweiten Gruppe anzuzeigen. Regex hilft so sehr bei der Überprüfung. –

+0

@ som-snytt Danke, mein Regex Foo ist ziemlich begrenzt –

3

Sie es fast haben:

stringList.map(query => query.split(" ")) 

ist, was Sie wollen, nur eine weitere Karte hinzufügen, um Listen zu Tupeln zu ändern:

.map { list => list.head -> list.lift(1).getOrElse("5").toInt } 

oder diese stattdessen, wenn Sie bevorzugen:

.collect { 
    case Seq(a, b) => a -> b.toInt 
    case Seq(a) => a -> 5 
} 

(.collect ignoriert leise die o Häufigkeiten, bei denen weniger als ein oder mehr als zwei Elemente in der Liste enthalten sind. Sie können es durch ersetzen, wenn Sie es in solchen Fällen durch einen Fehler bevorzugen würden).