Scala: Elegancka konwersja ciągu znaków na wartość logiczną

84

W Javie możesz pisać Boolean.valueOf(myString). Jednak w Scali java.lang.Booleanjest ukryty, przez scala.Booleanktóry brakuje tej funkcji. Łatwo jest przełączyć się na oryginalną wersję boolean w Javie, ale to po prostu nie wydaje się właściwe.

Więc jakie jest jednowierszowe, kanoniczne rozwiązanie w Scali do wyodrębniania truez łańcucha?

David Crawshaw
źródło
Dlaczego po prostu nie użyć wyrażenia regularnego?
Kevin Meredith
3
To wcale nie brzmi prosto.
Jaime Hablutzel

Odpowiedzi:

144

Ach, jestem głupi. Odpowiedź jest myString.toBoolean.

David Crawshaw
źródło
9
Jeśli myString ma wartość null, Twój kod zgłosi wyjątek, wolę następną odpowiedź Try (myString.toBoolean) .getOrElse (false)
Carlos Verdes
2
Try(myString.toBoolean).getOrElse(false)przejdzie przez pracę polegającą na rzucaniu i łapaniu wyjątku. Option(myString).exists(_.toBoolean)unika tego dodatkowego wysiłku.
sfosdal
1
Używanie Try(myString.toBoolean).getOrElse(false)jest dobre. Czysto obsługuje niepasujący ciąg.
NKM
110

Co powiesz na to:

import scala.util.Try

Try(myString.toBoolean).getOrElse(false)

Jeśli ciąg wejściowy nie jest konwertowany na prawidłową wartość logiczną, falsejest zwracany w przeciwieństwie do zgłaszania wyjątku. To zachowanie bardziej przypomina zachowanie Java programu Boolean.valueOf(myString).

user24601
źródło
Myślę, że wyjątek jest tym, czego chcesz. Co się stanie, jeśli użytkownik wpisze „1” zamiast „prawda” lub coś innego? Takie podejście pozostawi taki błąd niewykryty. Ale teraz wiem o funkcji Try, która jest fajna.
user42723
16

Scala 2.13wprowadzone String::toBooleanOption, co w połączeniu z Option::getOrElse, zapewnia bezpieczny sposób wyodrębnienia Booleanjako String:

"true".toBooleanOption.getOrElse(false)  // true
"false".toBooleanOption.getOrElse(false) // false
"oups".toBooleanOption.getOrElse(false)  // false
Xavier Guihot
źródło
11

Uwaga: nie pisz new Boolean(myString)w Javie - zawsze używaj Boolean.valueOf(myString). Korzystanie z newwariantu niepotrzebnie tworzy Booleanobiekt; użycie valueOfwariantu tego nie robi.

Jesper
źródło
8

Problem myString.toBooleanpolega na tym, że zgłosi wyjątek, jeśli myString.toLowerCasenie jest dokładnie jednym z "true"lub "false"(nawet dodatkowy biały znak w ciągu spowoduje wyrzucenie wyjątku).

Jeśli chcesz uzyskać dokładnie to samo zachowanie java.lang.Boolean.valueOf, użyj go w pełni kwalifikowanego lub zaimportuj wartość Boolean pod inną nazwą, np import java.lang.{Boolean=>JBoolean}; JBoolean.valueOf(myString).. Lub wyraź swoją własną metodę, która obsługuje własnych szczególnych okolicznościach (np, można "t"być truerównież).

Kristian Domagala
źródło
1
To nie jest prawda (już). toLowerCase is done by toBoolean`
pme
1

Bawiłem się tym dzisiaj, mapując zestaw wartości 1/0 na boolean. Musiałem wrócić do Spark 1.4.1 i w końcu udało mi się to współpracować z:

Try(if (p(11).toString == "1" || p(11).toString == "true") true else false).getOrElse(false)) 

gdzie p (11) jest polem ramki danych

moja poprzednia wersja nie miała opcji „Wypróbuj”, to działa, dostępne są inne sposoby ...

TobyEvans
źródło
2
Nie potrzebujesz elementu ifz, true else falseponieważ zwroty warunkowe truelub false. Wszystko czego potrzebujesz to Try(condition).getOrElse(false).
jwvh