切片显示在具有行和列的列表中

时间:2019-07-10 04:20:06

标签: string go slice golang-migrate

我有24个单词的切片,我想以列表格式显示4行6列的切片。我正在尝试在Go中实现它。

package main

import (
    "fmt"
)

func main() {
    words := []string{"peace", "note", "vapor", "notice", "meat", "shed", "immune", "law", "web", "security", "estate", "chat", "biology", "because", "visit", "inch", "credit", "void", "ability", "police", "crush", "begin", "matrix", "wreck"}
    for i, s := range words {
        fmt.Println(i, s)
    }
}

必填输出:

1.peace      7.immune         
2.note       8.law
3.vapor      9.web
4.notice     10.security
5.meat       11.estate
6.shed       12 chat

2 个答案:

答案 0 :(得分:3)

这是一种方法。您已经在必需的输出中显示了6行,但是提到了有问题的6列。 Link to playground

package main

import (
    "fmt"
    "strconv"
)

func main() {
    fmt.Println("Hello, playground")
    words := [] string{"peace", "note", "vapor", "notice", "meat", "shed", "immune", "law", "web", "security", "estate", "chat", "biology", "because", "visit", "inch", "credit", "void", "ability", "police", "crush", "begin", "matrix", "wreck"}
    for i := range words {

        words[i] = strconv.Itoa(i+1) + "." + words[i]
    }
    IterSplits(SliceSplit(words, 6), 6)
}

func IterSplits(slices[][] string, splitSize int){
    for i := 0; i < splitSize; i ++ {       
        for _, s := range slices {
            if len(s) > i {
                fmt.Printf("%-15v", s[i])
            }            
        }
        println("")     
    }   
}


func SliceSplit(aSlice[] string, splitSize int) [][]string{

  var splits [][]string 

  for i := 0; i < len(aSlice); i += splitSize {
    end := i + splitSize

    if end > len(aSlice) {
        end = len(aSlice)
    }

    splits = append(splits, aSlice[i:end])
  }

  return splits
}

答案 1 :(得分:2)

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个,则对于小于10的数字,我们可以使用1个空格,对于数字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上尝试这些。

注释#1:

以上解决方案包含“ wired in”元素的“ max width”。如果您不能做出这样的假设,则可以首先遍历元素以获取所有元素的最大宽度,然后在格式字符串中使用该宽度。

这是可以做到的:

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,则表示至少需要3行才能显示24个元素(2行最多只能在10列中显示20个元素)。但是,如果使用/利用3行,则3到8 = 24时,最多可以在8列中显示24个元素。