Пакет fmt
не имеет средств для перехода на одну строку в терминале.Есть управляющие символы, но они обычно зависят от терминала, поэтому мы должны избегать их, если сможем.
Мы можем достичь «табличного» макета, печатая элементы по строкам.Если у нас 4 строки и 6 столбцов, это означает, что первая строка будет содержать элемент 1., затем элемент 7., затем 13. и т. Д. Вторая строка будет содержать элемент 2., затем элемент 8., затемэлемент 14. и т. д.
В общем, у нас будет len(inputs) / cols
рядов, округленных в большую сторону.Вот как мы можем выразить это с помощью целочисленной арифметики:
rows := (len(input) + cols - 1) / cols
И элементы в строке будут иметь индексы:
i := col*rows + row // col goes from 0 to cols
Так что в основном мы можем использовать цикл for
,перебирая строки и печатая элементы строки.Мы можем использовать fmt.Printf()
со строкой формата, которая содержит индекс и элемент, используя одинаковую ширину для всех элементов (выровнено по левому краю), что-то вроде этого: "%d.%-11s"
(11 - это ширина дляэлементы, отрегулируйте это, если у вас есть более длинные вводимые тексты).
Индекс, однако, не всегда имеет одинаковую ширину.Например, индекс 3
имеет одну цифру, а 13
имеет 2 цифры.Таким образом, мы можем использовать «заполнение», чтобы каждый элемент и индекс занимали один и тот же индекс.Это заполнение может быть просто пробелами, и столько, сколько нужно, чтобы все индексы занимали одно и то же место.Например, если мы предположим, что у нас менее 100 элементов, то мы можем использовать 1 пробел для чисел, меньших 10, и без пробелов для чисел 10 ... 99.
Без лишних слов, вот наша простая table()
функция печати, она достаточно универсальна для определения количества столбцов и позаботится об остальном:
func table(input []string, cols int) {
rows := (len(input) + cols - 1) / cols
for row := 0; row < rows; row++ {
for col := 0; col < cols; col++ {
i := col*rows + row
if i >= len(input) {
break // This means the last column is not "full"
}
padding := ""
if i < 9 {
padding = " "
}
fmt.Printf("%d.%-11s%s", i+1, input[i], padding)
}
fmt.Println()
}
}
Давайте проверим это:
input := []string{
"one", "two", "three", "four", "five", "six",
"seven", "eight", "nine", "ten", "eleven", "twelve",
"thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
"nineteen", "twenty", "twenty-one", "twenty-two", "twenty-three", "twenty-four",
}
table(input, 6)
Для вышеприведенного мы получаем следующий вывод:
1.one 5.five 9.nine 13.thirteen 17.seventeen 21.twenty-one
2.two 6.six 10.ten 14.fourteen 18.eighteen 22.twenty-two
3.three 7.seven 11.eleven 15.fifteen 19.nineteen 23.twenty-three
4.four 8.eight 12.twelve 16.sixteen 20.twenty 24.twenty-four
Теперь давайте проверим с 5 столбцами, где последний столбец не будет "завершен":
table(input, 5)
На этот раз вы получите:
1.one 6.six 11.eleven 16.sixteen 21.twenty-one
2.two 7.seven 12.twelve 17.seventeen 22.twenty-two
3.three 8.eight 13.thirteen 18.eighteen 23.twenty-three
4.four 9.nine 14.fourteen 19.nineteen 24.twenty-four
5.five 10.ten 15.fifteen 20.twenty
Попробуйте их на Go Playground .
Note # 1:
Приведенное выше решение содержит «максимальную ширину» элементов, «подключенных».Если вы не можете сделать такое предположение, вы можете сначала перебрать элементы, чтобы получить максимальную ширину всех элементов, и использовать это в строке формата.
Вот как это можно сделать:
maxWidth := 0
for _, s := range input {
if len(s) > maxWidth {
maxWidth = len(s)
}
}
format := fmt.Sprintf("%%d.%%-%ds%%s", maxWidth)
Тогда это format
будет использоваться при печати элементов:
fmt.Printf(format, i+1, input[i], padding)
Попробуйте эту улучшенную версию на Go Playground .
Примечание # 2:
Также обратите внимание, что приведенный выше алгоритм может использовать меньше столбцов, чем вы передаете.Это происходит в духе «минимизации» столбцов.
Например, если длина ввода равна 24, а вы передаете cols=10
, это означает, что для представления 24 элементов необходимо минимум 3 строки (только 2 строки могутотображать не более 20 элементов в 10 столбцах).Но если используются / используются 3 строки, то 24 элемента могут быть представлены всего в 8 столбцах, потому что 3 * 8 = 24.