I made a function for this. This function has two parameters first for the map variable for columning, second is for how many characters do you want to fill to per line. It simply change key's value contents with spacing into new variable then prints that key, value. But if you have works with unmodified value you can use unmodified variable.
package main
import (
"fmt"
"errors"
"strings"
"sort"
)
func main() {
a := map[string]string{
"Key1": strings.Repeat("Value1", 50),
"Key2": strings.Repeat("Value2", 50),
"Key3": strings.Repeat("Value3", 50),
}
err := columner(a, 30)
if err != nil {
fmt.Println(err)
}
}
func columner(m map[string]string, charAmount int) error{
var keys []string
var keyLens []int
// to avoid index panics and gathering keys for later usage
for key, value := range m {
if charAmount > len(value) || charAmount < 1{
return errors.New("Error: charAmount neither be greather than length of key's value nor below 1")
}
keys = append(keys, key)
keyLens = append(keyLens, len(key))
}
sort.Ints(keyLens)
for i := 0; i < len(keys); i++ {
// for storing updated value of key
var value2 string
value := m[keys[i]]
// will used while extracting substring of key's value as first index
firstI := 0
// last index for extract substring from key's value. the len of substring will be same as charAmount
charAmount2 := charAmount
// will be used to advance next substring of key's value
advance := charAmount2
// spaces between between key and value
// key value
spacing := strings.Repeat(" ", 20 + (keyLens[0] - len(keys[i])))
// var for adjusting spaces of gap between key and value of next line
// key value
// value
// to
// key value
// value
spacingU := spacing + strings.Repeat(" ", len(keys[i]) + 1)
// this loop will be run as long as there is no substring left which exceed next line
for j := 0; j < len(value); j += advance {
// adjusting spaces of gap between key and value of next line
if j > 0 {
spacing = spacingU
}
// add space between key and value, then extract substring, then add spaces to the next line of the
// next substring of key's value
value2 += spacing + value[firstI:charAmount2] + "\n"
// finish loop when there is no substring that can be exceed to next line
if ((len(value) - charAmount2) < advance) || ((len(value) - charAmount2) == advance) {
break
}
// changing first index to start index of next substring of key's value
firstI = charAmount2
// advancing to next substring of key's value
charAmount2 += advance
}
// add last remaining substring of key's value to variable which will be show as formatted.
value2 += spacing + value[charAmount2:]
// show formatted key and value
fmt.Println(keys[i], value2, "\n")
}
return nil
}
This is a example output:
Key1 Value1Value1Value1Value1Value1
Value1Value1Value1Value1Value1
Value1Value1Value1Value1Value1
Value1Value1Value1Value1Value1
Value1Value1Value1Value1Value1
Value1Value1Value1Value1Value1
Value1Value1Value1Value1Value1
Value1Value1Value1Value1Value1
Value1Value1Value1Value1Value1
Value1Value1Value1Value1Value1
Key2 Value2Value2Value2Value2Value2
Value2Value2Value2Value2Value2
Value2Value2Value2Value2Value2
Value2Value2Value2Value2Value2
Value2Value2Value2Value2Value2
Value2Value2Value2Value2Value2
Value2Value2Value2Value2Value2
Value2Value2Value2Value2Value2
Value2Value2Value2Value2Value2
Value2Value2Value2Value2Value2
Key3 Value3Value3Value3Value3Value3
Value3Value3Value3Value3Value3
Value3Value3Value3Value3Value3
Value3Value3Value3Value3Value3
Value3Value3Value3Value3Value3
Value3Value3Value3Value3Value3
Value3Value3Value3Value3Value3
Value3Value3Value3Value3Value3
Value3Value3Value3Value3Value3
Value3Value3Value3Value3Value3
But please notice this, order of key and values may be different on each execution because map type is unordered when printed in for loop with key, value pair.