Reputation: 2157
I am trying to get the string out of the Set
type in Scala. However, no matter what I try it is returning Unit
as a return type instead of a string
.
if (!validationMessages.isEmpty) {
dataTuple = (parsedJson.toString(), for (s <- validationMessages.toString()){
s.toString()
})
println(dataTuple)
}
else {
dataTuple = (parsedJson.toString(), "some string...")
}
Basically, I am trying to return a tuple like (String, String)
. What am I missing?
Upvotes: 0
Views: 454
Reputation: 27356
The value of a block is the value of the last expression in the block. In this case the value of the if
part is
println(dataTuple)
and the value of the else
part is
dataTuple = (parsedJson.toString(), "some string...")
Both of these expressions return Unit
so the result is Unit
.
The quick fix is to make dataTuple
the last statement in each branch:
if (!validationMessages.isEmpty) {
dataTuple = (parsedJson.toString(), for (s <- validationMessages.toString()){
s.toString()
})
println(dataTuple)
dataTuple
} else {
dataTuple = (parsedJson.toString(), "some string...")
dataTuple
}
But also consider something like this as a simpler solution:
val msg =
if (validationMessages.nonEmpty) {
validationMessages.mkString(", ")
} else {
"some string"
}
(parsedJson.toString, msg)
The mkString
is an attempt to replace this code:
for (s <- validationMessages.toString()) {
s.toString()
}
This code appears to be trying to create a string by combining all the validation messages, but it actually returns Unit
because the for
does not have a yield
. mkString
calls toString
on each element of the Set
and then creates a string by putting ", " between each element. This seems to be roughly what is wanted and should be easy to modify to the actual requirement.
Upvotes: 5
Reputation: 182
Why is the code behaving like this?
That code has return type Unit
, because that is the return type of both branches of the if
statement.
The if
branch ends with println(dataTuple)
, which returns Unit
.
The else
branch ends with dataTuple = ...
, which is variable assignment, which returns Unit
. If you wanted it to return the tuple stored in dataTuple
, you'd just have to add dataTuple
to the end.
What do you probably want to do instead?
(parsedJson.toString, validationMessages.mkString("[", ", ", "]"))
That will return a tuple containing first parsedJson
as a string, and second, each element of validationMessages
, in arbitrary order (because Set
is unordered), starting with [
, with a ,
between consecutive elements, and ]
at the end.
So if parsedJson
was {"key1": "value1"}
and validationMessages
was Set("unexpected key: key1", "missing key: key0")
this would return ("{"key1":"value1"}",["unexpected key: key1", "missing key: key0"]
.
If you don't want to put something special at the beginning/end of your .mkString
, you can call it with only the middle argument (the delimiter).
If validationMessages
is empty, then validationMessages.mkString("delimiter")
returns an empty string, and validationMessages.mkString("start", "delimiter", "end")
returns "startend"
.
One of the beautiful things about scala is how you can do complex things in a single line (as long as you know the language well enough).
Upvotes: 4