print format adjust decimal point - scala

I like to print a lot of numbers between -1 and 1 and need them to be aligned by the decimal point.
What I get with %2.2f is:
val (a, b) = (0.38, -0.38); println (f"${a}%2.2f\n${b}%2.2f ")
0,38
-0,38
What I like to get is:
0,38
-0,38
Is there an elegant solution?

What you can actually do is to add -+ preceding the formatting likewise:
scala> val (a, b) = (0.38, -0.38); println (f"${a}%-+2.2f\n${b}%-+2.2f")
+0.38
-0.38
a: Double = 0.38
b: Double = -0.38
You will get the + before the number though.
EDIT:
If you know the number of digits of the numbers (the first number of %n.m indicates the length of the digits), you can actually go like:
scala> printf("%5.2f", a);
0.38
scala> printf("%5.2f", b);
-0.38

Although there is already an accepted answer, I'll add one more for future reference. Scala f"" string interpolator actually uses Java formatting infrastructure and in the Java documentation you may find following flag:
' ' '\u0020' Requires the output to include a single extra space ('\u0020') for non-negative values.
So you might actually want to use it. Here is an example that shows the difference:
val arr = Array(0.38, -0.38, 10.38, -10.38, 123.38, -123.38)
println("Without space:")
arr.foreach(a => println(f"${a}%6.2f"))
println("----------------")
println("With space:")
arr.foreach(a => println(f"${a}% 6.2f"))
which produces following output:
Without space:
0,38
-0,38
10,38
-10,38
123,38
-123,38
----------------
With space:
0,38
-0,38
10,38
-10,38
123,38
-123,38
note the difference for 123.38/-123.38 i.e. for the case when there is an "overflow"

The solution is trivial: The first number does not indicate digits before the dot, but digits total, and does not yield to an errormessage, if too short. So for 2 digits after the dot, plus dot, plus one in front and an optional minus sign, I need 5 digits in total, and then it works:
val (a, b) = (0.38, -0.38); println (f"${a}%5.2f\n${b}%5.2f ")
0,38
-0,38
And no, a plus sign is not an option.

Related

scala split ignore last values when empty

scala> val st1 = "|||||||000001|09/01/2014|V|174500,00|22||BD |2540|LEC|1000|BEB|
01|53||AE|111 ||49|94,22|6||||||||2|2|App|80|2|||"
scala> st1.split('|').length
resXX: Int = 39
scala> val st2 = "|||||||000001|09/01/2014|V|174500,00|22||BD |2540|LEC|1000|BEB|
01|53||AE|111 ||49|94,22|6||||||||2|2|App|80|2| | |"
scala> st2.split('|').length
resXX: Int = 41
that is the last empty fields are ignored by the split.
is there any solution other that replacing all "||" by "| |"
the expected output is Int = 41.
indeed in the real file I may have lines such as:
"|||||||000001|09/01/2014|V|174500,00|22||BD |2540|LEC|1000|BEB|
01|53||AE|111 ||49|94,22|6||||||||2|2|App|80|2|||150"
that is a 42nd column comprising a number. (In this case the result is Int = 42)
Every line has the same number of |, but depending on the content of the column, the split('|').length returns a different result! (31, 40, ...,42).
I can understand the lack of the column after the last separator, but not the lack of the previous ones.
This issue comes from Java (since that's where String#split is defined).
As you can see here, in the default case (which is limit=0), the trailing empty strings are discarded.
To make it work as you expect, you can use str.split('|', -1).

Most efficient way to format a string in scala with leading Zero's and a comma instead of a decimal point

Trying to create a simple function whereby a String value is passed in i.e. "1" and the formatter should return the value with leading zeros and 5 decimal points however instead of a dot '.' I'm trying to return it with a comma ','
This is what I have attempted however its not working because the decimalFormatter can only handle numbers and not a string. The end goal is to get from "1" to "000000001,00000" - character length is 14 in total. 5 0's after the comma and the remaining before the comma should be padded out 0's to fill the 9 digit requirement.
Another example would be going from "913" to "000000913,00000"
def numberFormatter (value: String): String =
{
import java.text.DecimalFormat
val decimalFormat = new DecimalFormat("%09d,00000")
val formattedValue = decimalFormat.format(value)
return formattedValue
}
Any help would be much appreciated. Thank you in advance.
It's easy enough to format a String padded with spaces, but with zeros not so much. Still, it's not so hard to roll your own.
def numberFormatter(value :String) :String =
("0" * (9 - value.length)) + value + ",00000"
numberFormatter("1") //res0: String = 000000001,00000
numberFormatter("913") //res1: String = 000000913,00000
Note that this won't truncate the input String. So if value is longer than 9 characters then the result will be longer than the desired 15 characters.
def f(value:String) = new java.text.DecimalFormat("000000000.00000").format(value.toFloat).replace(".", ",")
scala> f(913f)
res5: String = 000000913,00000
// Edit: Use .toFloat (or .toInt, .toLong, etc.) to convert your string to a number first.

How to calculate number of occurrence of a character at beginning in a List of String using Scala

I am new to Scala and I want to calculate number of occurrences of a character in which start with a particular alphabet in a list of Strings.
For example-
val test1 : List[String] = List("zero","zebra","zenith","tiger","mosquito")
I have defined above List of Strings and I want to calculate count of all strings which start with "z".
I tried with below code-
scala> test2.count(s=> s.charAt(0) == "z")
res7: Int = 0
It is giving me result as 0. I am not sure what I am doing wrong. Please suggest.
Character values are delimited by single quotes. Double quotes are reserved for strings:
val test : List[String] = List("zero","zebra","zenith","tiger","mosquito")
test.count(_.charAt(0) == 'z') // 3: Int
you can simply use filter and find the length of the list
println(test1.filter(_.startsWith("z")).length)
If you want to ignore the cases (uppercase or lowercase) you can add .toLowerCase as
println(test1.filter(_.toLowerCase.startsWith("z")).length)
I hope the answer is helpful

Zeroes and ones in binary number Scala

I have read some number of binary representation from a file, then I summed them up and tried to find the number of zeroes and one's occurrences.
The problem is that some digits get lost or whatever else happens, so the total number of digits in a sum is more than a sum of zeroes and one's.
Here is my code:
val binaryNums = Source.fromFile("path/task2.txt").getLines.map(BigInt(_)).toList
val sumOfBins = binaryNums.sum.toString
println("Zeroes occurrence " + sumOfBins.count(_ == '0'))
println("Ones occurrence " + sumOfBins.count(_ == '1'))
I would be really grateful if you helped me to find a mistake.
Update: File contents look like this (about 800 digits in each number)
.
By default toString converts the number to its decimal representation. To convert to binary you have to provide the radix argument to toString:
val sumOfBins = binaryNums.sum.toString(2)

How to strip everything except digits from a string in Scala (quick one liners)

This is driving me nuts... there must be a way to strip out all non-digit characters (or perform other simple filtering) in a String.
Example: I want to turn a phone number ("+72 (93) 2342-7772" or "+1 310-777-2341") into a simple numeric String (not an Int), such as "729323427772" or "13107772341".
I tried "[\\d]+".r.findAllIn(phoneNumber) which returns an Iteratee and then I would have to recombine them into a String somehow... seems horribly wasteful.
I also came up with: phoneNumber.filter("0123456789".contains(_)) but that becomes tedious for other situations. For instance, removing all punctuation... I'm really after something that works with a regular expression so it has wider application than just filtering out digits.
Anyone have a fancy Scala one-liner for this that is more direct?
You can use filter, treating the string as a character sequence and testing the character with isDigit:
"+72 (93) 2342-7772".filter(_.isDigit) // res0: String = 729323427772
You can use replaceAll and Regex.
"+72 (93) 2342-7772".replaceAll("[^0-9]", "") // res1: String = 729323427772
Another approach, define the collection of valid characters, in this case
val d = '0' to '9'
and so for val a = "+72 (93) 2342-7772", filter on collection inclusion for instance with either of these,
for (c <- a if d.contains(c)) yield c
a.filter(d.contains)
a.collect{ case c if d.contains(c) => c }