1

I have some collection like List or Array of Int of unknown length, each one or two digits, and want to print each in the width of 4, for example:

  a   b   c
 11   9  12
  7  12   1

I hoped there is something like:

List("a", "b", "c").mkString(s"%3s ")
val li = List(11, 9, 12) 
li.mkString(s"%3d ")

but there isn't, at least not where I looked for it.

Is there an elegant solution? Can I use a foldLeft? Somehow, I don't get it:

(0 to 2).foldLeft("")((sofar, idx) => sofar + s"%3d${li(idx)} ")

results in an unprintable "%3d11 %3d9 %3d12 "

For 3 Elements, a literal formatting is easy

printf (s"%3d %3d %3d", li(0), li(1), li(2))
 11   9  12

But for more elements, especially for an unknown number of elements, how do I solve this elegantly?

user
  • 7,435
  • 3
  • 14
  • 44
user unknown
  • 35,537
  • 11
  • 75
  • 121

2 Answers2

3

Turn each element into a String of the desired format before the mkString.

Seq(23,5,111,7).map(n => f"$n%4d").mkString
//res0: String = "  23   5 111   7"

Or, alternatively, you might construct a single format String and then format() the collection.

val nums = Array(1, 22, 3, 444)
("%4d" * nums.length).format(nums:_*)
//res1: String = "   1  22   3 444"
jwvh
  • 50,871
  • 7
  • 38
  • 64
1

More options you have, base on the great How to convert an Int to a String of a given length with leading zeros to align?:

Seq(11, 9, 12).map(n => "%4d".format(n)).mkString

Or:

Seq(11, 9, 12).map(_.toString.reverse.padTo(4, ' ').reverse).mkString

Or using foldLeft:

Seq(11, 9, 12).foldLeft("")((soFar, i) => soFar + "%4d".format(i))

Code run at Scastie.

Tomer Shetah
  • 8,413
  • 7
  • 27
  • 35