У меня есть некоторая коллекция типа List или Array of Int неизвестной длины, каждая из которых состоит из одной или двух цифр, и я хочу вывести каждую из них шириной 4, например:

  a   b   c
 11   9  12
  7  12   1

Я надеялся, что есть что-то вроде:

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

но его нет, по крайней мере, там, где я его искал.

Есть ли элегантное решение? Могу ли я использовать foldLeft? Почему-то я не понимаю:

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

приводит к непечатаемому "%3d11 %3d9 %3d12"

Для 3 элементов буквальное форматирование не составляет труда

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

Но для большего количества элементов, особенно для неизвестного количества элементов, как мне элегантно решить эту проблему?

Ответы (2)

Превратите каждый элемент в String нужного формата перед mkString.

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

Или, в качестве альтернативы, вы можете создать один формат String, а затем format() коллекцию.

val nums = Array(1, 22, 3, 444)
("%4d" * nums.length).format(nums:_*)
//res1: String = "   1  22   3 444"

Больше вариантов у вас есть, основываясь на замечательном Как преобразовать Int в строку заданной длины с ведущими нулями для выравнивания?:

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

Или:

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

Или используя foldLeft:

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

Код выполняется на Scastie.

2022 WebDevInsider