How to convert an int value to string in Go? - string

i := 123
s := string(i)
s is 'E', but what I want is "123"
Please tell me how can I get "123".
And in Java, I can do in this way:
String s = "ab" + "c" // s is "abc"
how can I concat two strings in Go?

Use the strconv package's Itoa function.
For example:
package main
import (
"strconv"
"fmt"
)
func main() {
t := strconv.Itoa(123)
fmt.Println(t)
}
You can concat strings simply by +'ing them, or by using the Join function of the strings package.

fmt.Sprintf("%v",value);
If you know the specific type of value use the corresponding formatter for example %d for int
More info - fmt

fmt.Sprintf, strconv.Itoa and strconv.FormatInt will do the job. But Sprintf will use the package reflect, and it will allocate one more object, so it's not an efficient choice.

It is interesting to note that strconv.Itoa is shorthand for
func FormatInt(i int64, base int) string
with base 10
For Example:
strconv.Itoa(123)
is equivalent to
strconv.FormatInt(int64(123), 10)

You can use fmt.Sprintf or strconv.FormatFloat
For example
package main
import (
"fmt"
)
func main() {
val := 14.7
s := fmt.Sprintf("%f", val)
fmt.Println(s)
}

In this case both strconv and fmt.Sprintf do the same job but using the strconv package's Itoa function is the best choice, because fmt.Sprintf allocate one more object during conversion.
check the benchmark here: https://gist.github.com/evalphobia/caee1602969a640a4530
see https://play.golang.org/p/hlaz_rMa0D for example.

Converting int64:
n := int64(32)
str := strconv.FormatInt(n, 10)
fmt.Println(str)
// Prints "32"

Another option:
package main
import "fmt"
func main() {
n := 123
s := fmt.Sprint(n)
fmt.Println(s == "123")
}
https://golang.org/pkg/fmt#Sprint

ok,most of them have shown you something good.
Let'me give you this:
// ToString Change arg to string
func ToString(arg interface{}, timeFormat ...string) string {
if len(timeFormat) > 1 {
log.SetFlags(log.Llongfile | log.LstdFlags)
log.Println(errors.New(fmt.Sprintf("timeFormat's length should be one")))
}
var tmp = reflect.Indirect(reflect.ValueOf(arg)).Interface()
switch v := tmp.(type) {
case int:
return strconv.Itoa(v)
case int8:
return strconv.FormatInt(int64(v), 10)
case int16:
return strconv.FormatInt(int64(v), 10)
case int32:
return strconv.FormatInt(int64(v), 10)
case int64:
return strconv.FormatInt(v, 10)
case string:
return v
case float32:
return strconv.FormatFloat(float64(v), 'f', -1, 32)
case float64:
return strconv.FormatFloat(v, 'f', -1, 64)
case time.Time:
if len(timeFormat) == 1 {
return v.Format(timeFormat[0])
}
return v.Format("2006-01-02 15:04:05")
case jsoncrack.Time:
if len(timeFormat) == 1 {
return v.Time().Format(timeFormat[0])
}
return v.Time().Format("2006-01-02 15:04:05")
case fmt.Stringer:
return v.String()
case reflect.Value:
return ToString(v.Interface(), timeFormat...)
default:
return ""
}
}

package main
import (
"fmt"
"strconv"
)
func main(){
//First question: how to get int string?
intValue := 123
// keeping it in separate variable :
strValue := strconv.Itoa(intValue)
fmt.Println(strValue)
//Second question: how to concat two strings?
firstStr := "ab"
secondStr := "c"
s := firstStr + secondStr
fmt.Println(s)
}

Related

Split string along regex, but keep matches

I want to split a string on a regular expresion, but preserve the matches.
I have tried splitting the string on a regex, but it throws away the matches. I have also tried using this, but I am not very good at translating code from language to language, let alone C#.
re := regexp.MustCompile(`\d`)
array := re.Split("ab1cd2ef3", -1)
I need the value of array to be ["ab", "1", "cd", "2", "ef", "3"], but the value of array is ["ab", "cd", "ef"]. No errors.
The kind of regex support in the link you have pointed out is NOT available in Go regex package. You can read the related discussion.
What you want to achieve (as per the sample given) can be done using regex to match digits or non-digits.
package main
import (
"fmt"
"regexp"
)
func main() {
str := "ab1cd2ef3"
r := regexp.MustCompile(`(\d|[^\d]+)`)
fmt.Println(r.FindAllStringSubmatch(str, -1))
}
Playground: https://play.golang.org/p/L-ElvkDky53
Output:
[[ab ab] [1 1] [cd cd] [2 2] [ef ef] [3 3]]
I don't think this is possible with the current regexp package, but the Split could be easily extended to such behavior.
This should work for your case:
func Split(re *regexp.Regexp, s string, n int) []string {
if n == 0 {
return nil
}
matches := re.FindAllStringIndex(s, n)
strings := make([]string, 0, len(matches))
beg := 0
end := 0
for _, match := range matches {
if n > 0 && len(strings) >= n-1 {
break
}
end = match[0]
if match[1] != 0 {
strings = append(strings, s[beg:end])
}
beg = match[1]
// This also appends the current match
strings = append(strings, s[match[0]:match[1]])
}
if end != len(s) {
strings = append(strings, s[beg:])
}
return strings
}
Dumb solutions. Add separator in the string and split with separator.
package main
import (
"fmt"
"regexp"
"strings"
)
func main() {
re := regexp.MustCompile(`\d+`)
input := "ab1cd2ef3"
sep := "|"
indexes := re.FindAllStringIndex(input, -1)
fmt.Println(indexes)
move := 0
for _, v := range indexes {
p1 := v[0] + move
p2 := v[1] + move
input = input[:p1] + sep + input[p1:p2] + sep + input[p2:]
move += 2
}
result := strings.Split(input, sep)
fmt.Println(result)
}
You can use a bufio.Scanner:
package main
import (
"bufio"
"strings"
)
func digit(data []byte, eof bool) (int, []byte, error) {
for i, b := range data {
if '0' <= b && b <= '9' {
if i > 0 {
return i, data[:i], nil
}
return 1, data[:1], nil
}
}
return 0, nil, nil
}
func main() {
s := bufio.NewScanner(strings.NewReader("ab1cd2ef3"))
s.Split(digit)
for s.Scan() {
println(s.Text())
}
}
https://golang.org/pkg/bufio#Scanner.Split

Go: how to check if a string contains multiple substrings?

strings.Contains(str_to_check, substr) takes only one argument as the substring to check, how do I check multiple substrings without using strings.Contains() repeatedly?
eg. strings.Contains(str_to_check, substr1, substr2)
Yes, you can do this without calling strings.Contains() multiple times.
If you know substrings in advance the easiest way to check this with regular expression. And if a string to check is long and you have quite a few substrings it can be more fast then calling multiple strings.Contains
Example https://play.golang.org/p/7PokxbOOo7:
package main
import (
"fmt"
"regexp"
)
var re = regexp.MustCompile(`first|second|third`)
func main() {
fmt.Println(re.MatchString("This is the first example"))
fmt.Println(re.MatchString("This is the second example after first"))
fmt.Println(re.MatchString("This is the third example"))
fmt.Println(re.MatchString("This is the forth example"))
}
Output:
true
true
true
false
If the subs to check are dynamic it may be a bit more difficult to create regex as you need to escape special characters and regex compilation is not fast so strings.Contains() may be better in this case though it's better test if your code is performance critical.
Another good option could be to write your own scanner that can leverage common prefixes in substrings (if any) using prefix tree.
You can write your own utility function using strings.Contains() that can work for multiple sub-strings.
Here's an example that returns Boolean (true/false) in case of complete / partial match and the total number of matches:
package main
import (
"fmt"
"strings"
)
func checkSubstrings(str string, subs ...string) (bool, int) {
matches := 0
isCompleteMatch := true
fmt.Printf("String: \"%s\", Substrings: %s\n", str, subs)
for _, sub := range subs {
if strings.Contains(str, sub) {
matches += 1
} else {
isCompleteMatch = false
}
}
return isCompleteMatch, matches
}
func main() {
isCompleteMatch1, matches1 := checkSubstrings("Hello abc, xyz, abc", "abc", "xyz")
fmt.Printf("Test 1: { isCompleteMatch: %t, Matches: %d }\n", isCompleteMatch1, matches1)
fmt.Println()
isCompleteMatch2, matches2 := checkSubstrings("Hello abc, abc", "abc", "xyz")
fmt.Printf("Test 2: { isCompleteMatch: %t, Matches: %d }\n", isCompleteMatch2, matches2)
}
Output:
String: "Hello abc, xyz, abc", Substrings: [abc xyz]
Test 1: { isCompleteMatch: true, Matches: 2 }
String: "Hello abc, abc", Substrings: [abc xyz]
Test 2: { isCompleteMatch: false, Matches: 1 }
Here's the live example: https://play.golang.org/p/Xka0KfBrRD
Another solution would be using a combination of regexp and suffixarray. From the documentation:
Package suffixarray implements substring search in logarithmic time using an in-memory suffix array.
package main
import (
"fmt"
"index/suffixarray"
"regexp"
"strings"
)
func main() {
fmt.Println(contains("first secondthird", "first", "second", "third"))
fmt.Println(contains("first secondthird", "first", "10th"))
}
func contains(str string, subStrs ...string) bool {
if len(subStrs) == 0 {
return true
}
r := regexp.MustCompile(strings.Join(subStrs, "|"))
index := suffixarray.New([]byte(str))
res := index.FindAllIndex(r, -1)
exists := make(map[string]int)
for _, v := range subStrs {
exists[v] = 1
}
for _, pair := range res {
s := str[pair[0]:pair[1]]
exists[s] = exists[s] + 1
}
for _, v := range exists {
if v == 1 {
return false
}
}
return true
}
(In Go Playground)
[H]ow do I check multiple substrings without using strings.Contains() repeatedly?
Not at all. You have to call Contains repeatedly.

Access a string as a character array for using in strings.Join() method: GO language

I am trying to access a string as a character array or as a rune and join with some separator. What is the right way to do it.
Here are the two ways i tried but i get an error as below
cannot use ([]rune)(t)[i] (type rune) as type []string in argument to strings.Join
How does a string represented in GOLANG. Is it like a character array?
package main
import (
"fmt"
"strings"
)
func main() {
var t = "hello"
s := ""
for i, rune := range t {
s += strings.Join(rune, "\n")
}
fmt.Println(s)
}
package main
import (
"fmt"
"strings"
)
func main() {
var t = "hello"
s := ""
for i := 0; i < len(t); i++ {
s += strings.Join([]rune(t)[i], "\n")
}
fmt.Println(s)
}
I also tried the below way.BUt, it does not work for me.
var t = "hello"
s := ""
for i := 0; i < len(t); i++ {
s += strings.Join(string(t[i]), "\n")
}
fmt.Println(s)
The strings.Join method expects a slice of strings as first argument, but you are giving it a rune type.
You can use the strings.Split method to obtain a slice of strings from a string. Here is an example.

golang - how to sort string or []byte?

I am looking for a function, that can sort string or []byte:
"bcad" to "abcd"
or
[]byte("bcad") to []byte("abcd")
The string only contains letters - but sorting should also work for letters and numbers.
I found sort package but not the function I want.
It feels wasteful to create a string for each character just to Join them.
Here's one that is a little less wasteful, but with more boiler plate. playground://XEckr_rpr8
type sortRunes []rune
func (s sortRunes) Less(i, j int) bool {
return s[i] < s[j]
}
func (s sortRunes) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s sortRunes) Len() int {
return len(s)
}
func SortString(s string) string {
r := []rune(s)
sort.Sort(sortRunes(r))
return string(r)
}
func main() {
w1 := "bcad"
w2 := SortString(w1)
fmt.Println(w1)
fmt.Println(w2)
}
You can convert the string to a slice of strings, sort it, and then convert it back to a string:
package main
import (
"fmt"
"sort"
"strings"
)
func SortString(w string) string {
s := strings.Split(w, "")
sort.Strings(s)
return strings.Join(s, "")
}
func main() {
w1 := "bcad"
w2 := SortString(w1)
fmt.Println(w1)
fmt.Println(w2)
}
This prints:
bcad
abcd
Try it: http://play.golang.org/p/_6cTBAAZPb
there is a simple way by leveraging function sort.Slice:
package main
import (
"fmt"
"sort"
)
func main() {
word := "1BCagM9"
s := []rune(word)
sort.Slice(s, func(i int, j int) bool { return s[i] < s[j] })
fmt.Println(string(s))
}
(Playground)
package main
import (
"fmt"
"sort"
)
func main() {
word := "1àha漢字Pépy5"
charArray := []rune(word)
sort.Slice(charArray, func(i int, j int) bool {
return charArray[i] < charArray[j]
})
fmt.Println(string(charArray))
}
Output:
15Pahpyàé字漢
Playground
the thing is, golang does not have a convenient function to sort string.
Sort using int
too much conversion i think
still using rune to merge as string
func sortByInt(s string) string {
var si = []int{}
var sr = []rune{}
for _, r := range s {
si = append(si, int(r))
}
sort.Ints(si)
for _, r := range si {
sr = append(sr, rune(r))
}
return string(sr)
}
Implement sort interface for []rune, just remember that
rune equals to int32
byte equals to uint8
func sortBySlice(s string) []rune {
sr := []rune(s)
sort.Slice(sr, func(i int, j int) bool {
return sr[i] < sr[j]
})
return sr
}
You can sort a string array in go like this
// name of the file is main.go
package main
import (
"fmt"
"sort"
)
/*
*This function is used to sort a string array
*/
func main() {
var names = []string{"b", "e", "a", "d", "g", "c", "f"}
fmt.Println("original string array: ", names)
sort.Strings(names)
fmt.Println("After string sort array ", names)
return
}

Position in characters of a substring in Go

How can I know the position of a substring in a string, in characteres (or runes) instead of bytes?
strings.Index(s, sub) will give the position in bytes. When using Unicode, it doesn't match the position in runes: http://play.golang.org/p/DnlFjPaD2j
func main() {
s := "áéíóúÁÉÍÓÚ"
fmt.Println(strings.Index(s, "ÍÓ"))
}
Result: 14. Expected: 7
Of course, I could convert s and sub to []rune and look for the subslice manually, but is there a better way to do it?
Related to this, to get the first n characters of a string I'm doing this: string([]rune(s)[:n]). Is it the best way?
You can do it like this, after importing the unicode/utf8 package:
func main() {
s := "áéíóúÁÉÍÓÚ"
i := strings.Index(s, "ÍÓ")
fmt.Println(utf8.RuneCountInString(s[:i]))
}
http://play.golang.org/p/Etszu3rbY3
Another option:
package main
import "strings"
func runeIndex(s, substr string) int {
n := strings.Index(s, substr)
if n == -1 { return -1 }
r := []rune(s[:n])
return len(r)
}
func main() {
n := runeIndex("áéíóúÁÉÍÓÚ", "ÍÓ")
println(n == 7)
}

Resources