When doing format string interpolation in Sweden I get a comma instead of a dot when creating strings with decimal numbers:
scala> val a = 5.010
a: Double = 5.01
scala> val a = 5.0101
a: Double = 5.0101
scala> f"$a%.2f"
res0: String = 5,01
My question is, how do I set the format so that I get the result 5.01? I would like to be able to set the locale only for that String, i.e. so that I don't change the locale for the whole environment.
Cheers,
Johan
Using the same Java library number formatting support accessible
from StringOps enriched String class, you could specify another locale just for that output:
"%.2f".formatLocal(java.util.Locale.US, a)
(as described in "How to convert an Int to a String of a given length with leading zeros to align?")
The Scala way would be to use the string f interpolator (Scala 2.10+), as in the OP's question, but it is using the "current locale", without offering an easy way to set that locale to a different one just for one call.
Locale.setDefault(Locale.US)
println(f"$a%.2f")
Related
I'm trying to create a raw string that contains three quotes in itself.
The resulting string x should contain something like """abc""".
I've been able to create the string with the following code, but was wondering if there's a simpler solution for this.
val x = """${'"'.toString().repeat(3)}abc${'"'.toString().repeat(3)}"""
There's no easy way to use a triple quote directly in a string literal.
One workaround I've sometimes used is to make an interim variable to hold the triple-quote string.
val quotes = "\"\"\""
val result = "${quotes}abc${quotes}"
I think a simpler way would be to escape them manually, so like:
val x = "\"\"\"abc\"\"\""
I'm a new learner of spark. There's one line of code estimating pi but I don't quite understand how it works.
scala>val pi_approx = f"pi = ${355f/113}%.5f"
pi_approx: String = pi = 3.14159
I don't understand the 'f' '$' and '%' in the expression above. Could anyone explain the usage of them? Thanks!
This is the example of String Interpolation that allows users to embed variable references directly in processed string literals. For e.g.
scala> val name = "Scala"
name: String = Scala
scala> println(s"Hello, $name")
Hello, Scala
In above example the literal s"Hello, $name" is a processed string literal.
Scala provides three string interpolation methods out of the box: s, f and raw.
Prepending f to any string literal allows the creation of simple formatted strings, similar to printf in other languages.
The formats allowed after the % character tells that result is formatted as a decimal number while ${} allows any arbitrary expression to be embedded. For e.g.
scala> println(s"1 + 1 = ${1 + 1}")
1 + 1 = 2
More detailed information can be found on:
Scala String Interpolation
Java Formatter
I'm trying to compose a formatted string that should look like this:
A bottle of vodka costs x.yz rubles.
where x.yz is an arbitrary Double value rounded to 2 decimal signs.
To achieve this, I use string interpolation with printf syntax:
val cost = 2.56
val str = f"A bottle of vodka costs $cost%.2f rubles."
Unfortunately, on a machine with Russian locale, the snippet above yields a result that is a bit different from what I want to achieve:
str: String = A bottle of vodka costs 2,56 rubles.
This is understandable (the Java formatter used by f interpolator applies the locale-specific decimal separator, as outlined here), but I still want to use decimal dot instead of comma.
I'm aware of a possible workaround – using the formatLocal() method with explicitly set locale:
val str = "A bottle of vodka costs %.2f rubles.".formatLocal(java.util.Locale.US, cost)
but it does not strike me as a particularly Scalaesque way of doing things.
So my question is this: is it possible to format a string with a specific decimal separator using only f interpolation, without any extraneous method calls?
At the moment f interpolator does not support locales nor custom separators (see macro_StringInterpolation_f.scala / FastTrack.scala).
Scala has triple quoted strings """String\nString""" to use special characters in the string without escaping. Scala 2.10 also added raw"String\nString" for the same purpose.
Is there any difference in how raw"" and """""" work? Can they produce different output for the same string?
Looking at the source for the default interpolators (found here: https://github.com/scala/scala/blob/2.11.x/src/library/scala/StringContext.scala) it looks like the "raw" interpolator calls the identity function on each letter, so what you put in is what you get out. The biggest difference that you will find is that if you are providing a string literal in your source that includes the quote character, the raw interpolator still won't work. i.e. you can't say
raw"this whole "thing" should be one string object"
but you can say
"""this whole "thing" should be one string object"""
So you might be wondering "Why would I ever bother using the raw interpolator then?" and the answer is that the raw interpolator still performs variable substitution. So
val helloVar = "hello"
val helloWorldString = raw"""$helloVar, "World"!\n"""
Will give you the string "hello, "World"!\n" with the \n not being converted to a newline, and the quotes around the word world.
It is surprising that using the s-interpolator turns escapes back on, even when using triple quotes:
scala> "hi\nthere."
res5: String =
hi
there.
scala> """hi\nthere."""
res6: String = hi\nthere.
scala> s"""hi\nthere."""
res7: String =
hi
there.
The s-interpolator doesn't know that it's processing string parts that were originally triple-quoted. Hence:
scala> raw"""hi\nthere."""
res8: String = hi\nthere.
This matters when you're using backslashes in other ways, such as regexes:
scala> val n = """\d"""
n: String = \d
scala> s"$n".r
res9: scala.util.matching.Regex = \d
scala> s"\d".r
scala.StringContext$InvalidEscapeException: invalid escape character at index 0 in "\d"
at scala.StringContext$.loop$1(StringContext.scala:231)
at scala.StringContext$.replace$1(StringContext.scala:241)
at scala.StringContext$.treatEscapes0(StringContext.scala:245)
at scala.StringContext$.treatEscapes(StringContext.scala:190)
at scala.StringContext$$anonfun$s$1.apply(StringContext.scala:94)
at scala.StringContext$$anonfun$s$1.apply(StringContext.scala:94)
at scala.StringContext.standardInterpolator(StringContext.scala:124)
at scala.StringContext.s(StringContext.scala:94)
... 33 elided
scala> s"""\d""".r
scala.StringContext$InvalidEscapeException: invalid escape character at index 0 in "\d"
at scala.StringContext$.loop$1(StringContext.scala:231)
at scala.StringContext$.replace$1(StringContext.scala:241)
at scala.StringContext$.treatEscapes0(StringContext.scala:245)
at scala.StringContext$.treatEscapes(StringContext.scala:190)
at scala.StringContext$$anonfun$s$1.apply(StringContext.scala:94)
at scala.StringContext$$anonfun$s$1.apply(StringContext.scala:94)
at scala.StringContext.standardInterpolator(StringContext.scala:124)
at scala.StringContext.s(StringContext.scala:94)
... 33 elided
scala> raw"""\d$n""".r
res12: scala.util.matching.Regex = \d\d
There is a string containing a number in an arbitrary format (e.g., 12, -34.5, and 6.78e-9). The goal is to convert this string into the corresponding number and then convert this number back to a string such that (a) the precision given in the original string is preserved, and (b) the resulting string has an adequate format (probably, the most adequate format is the format of the original string). I thought the problem could be easily solved using str2num and num2str; however, in some cases, MATLAB seems to be mangling the final result as shown below:
>> a = '1e23'
a =
1e23
>> b = str2num(a)
b =
1.0000e+23
>> c = num2str(b)
c =
9.999999999999999e+22
One solution is to use a general format string:
>> c = num2str(b, '%e')
c =
1.000000e+23
However, in this case, the output looks rather cumbersome for numbers of small orders:
>> d = num2str(1, '%e')
d =
1.000000e+00
In most cases, num2str without additional parameters does a pretty good job resulting in a nicely formatted string. The question is: Is there a way to eliminate the 9.999999999999999e+22 problem?
Thank you!
Regards,
Ivan
In general the representation of one input string does not contain enough information to determine the format. Hence (assuming you want to output slightly different numbers and cannot simply store the number in string format), the simplest way would be to try and find a format that you like.
Judging from your comments, I think you will be happy with:
format short g
For large numbers it will give:
x = num2str(1.0000e+23);str2num(x)
ans =
1e+23
And for small numbers:
x = num2str(1);str2num(x)
ans =
1