Reputation: 20650
case class Account(
val name: String,
val uuid: String,
val lat: Double,
val lng: Double
)
}
object Account {
def create(row: Row): Option[YellowAccount] = {
val name = row.getAs[String]("store_name")
val uuid = row.getAs[String]("uuid")
val latO = row.getAs[String]("latitude")
val lngO = row.getAs[String]("longitude")
// How do you do null checks here in an idiomatic way?
if (latO == null || lngO == null) {
return None
}
Some(YellowAccount(name, uuid, latO.toDouble, lngO.toDouble))
}
}
lat/long are compulsory fields in Account
. How do you do null checks in an idiomatic way?
Upvotes: 3
Views: 1053
Reputation: 40508
As the other answer suggests, you can use Option
to handle possible nulls. You can't use for
comprehension the way it is suggested there, but there are several ways around it. The easiest, probably is to .zip
the two Options together, and then map over the result:
Option(row.getAs[latitude])
.zip(Option(row.getAs[String]("longitude")))
.map { case (lat, long) =>
YellowAccount(
row.getAs[String]("store_name"),
row.getAs[String]("uuid"),
lat.toDouble,
long.toDouble
)
}
Upvotes: 0
Reputation: 6460
You can use Option
type to handle null
values. You just wrap a nullable value in Option
and then you can pattern match on it or something else. In your example, I think the most concise way to combine 4 nullable values is for-comprehension:
import scala.util.Try
object Account {
def create(row: Row): Option[YellowAccount] = {
for {
name <- Option( row.getAs[String]("store_name") )
uuid <- Option( row.getAs[String]("uuid") )
latO <- Try( row.getAs[String]("latitude").toDouble ).toOption
lngO <- Try( row.getAs[String]("longitude").toDouble ).toOption
} yield
YellowAccount(name, uuid, latO, lngO)
}
}
EDIT
Another thing here is _.toDouble
conversion, which may throw an exception if it fails to parse the string, so you can wrap it in Try
instead (I updated the code above).
EDIT2
To clarify what's happening here:
Option
it becomes None
if the value is null
, or Some(...)
with the value otherwiseTry
, it becomes either Failure
with the exception, or Success
with the valuetoOption
method converts Try
to Option
in a straightforward way: Failure
becomes None
, Success
becomes Some
Option
s returns None
(i.e. one of them was null
of failed to parse a number), the whole statement returns None
, and only if each of the four yields a value, they are passed to the YellowAccount
constructorUpvotes: 5