Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to replace a letter at a specific index in a string in Go?

Tags:

string

go

I want to replace a letter at a specific index in a string: aaaaaaa -> aaabaaa. Is there a built in way to do this? I wrote the following helper function to use in the mean time:

func main() {     input := "aaaaaaa"     output := replaceAtIndex(input, 'b', 3) }  func replaceAtIndex(input string, replacement byte, index int) string {     return strings.Join([]string{input[:index], string(replacement), input[index+1:]}, "") } 
like image 279
Ferguzz Avatar asked Jul 22 '14 17:07

Ferguzz


People also ask

How do you replace a character in a string at a specific index?

Unlike String Class, the StringBuilder class is used to represent a mutable string of characters and has a predefined method for change a character at a specific index – setCharAt(). Replace the character at the specific index by calling this method and passing the character and the index as the parameter.

Can I change a specific character in a string in Golang?

The strings package of Golang has a Replace() function which we can use to replace some characters in a string with a new value. It replaces only a specified "n" occurrences of the substring.

How do you replace a specific letter in a string?

Using 'str.replace() , we can replace a specific character. If we want to remove that specific character, replace that character with an empty string. The str. replace() method will replace all occurrences of the specific character mentioned.

How do you replace a word in a string in Golang?

Replace() Function in Golang is used to return a copy of the given string with the first n non-overlapping instances of old replaced by new one. Here, s is the original or given string, old is the string that you want to replace. new is the string which replaces the old, and n is the number of times the old replaced.


2 Answers

Strings are immutable in Go, you have to convert it to runes then modify it then convert it back to a string.

@chendesheng's solution is semi-correct, except you can use rune instead of byte, that way it will work on unicode as well.

func replaceAtIndex(in string, r rune, i int) string {     out := []rune(in)     out[i] = r     return string(out) } 

playground

like image 171
OneOfOne Avatar answered Sep 22 '22 09:09

OneOfOne


Both of the answers (OneOfOne and Denys Séguret) are correct. I just wanted to show the performance difference between them (which is really noticeable when the string is big).

It turns out that using str[:index] + string(replacement) + str[index+1:] is way faster.

So the benchmark:

package main import (     "testing" )  func replaceAtIndex1(str string, replacement rune, index int) string {     out := []rune(str)     out[index] = replacement     return string(out) }  func replaceAtIndex2(str string, replacement rune, index int) string {     return str[:index] + string(replacement) + str[index+1:] }  func generateString(n int) string{     s := ""     for i := 0; i < n; i++{         s += "a"     }     return s }  func BenchmarkSmall1(b *testing.B) {     n := 10     str, index, replacement := generateString(n), n / 2, 'B'      b.ResetTimer()     for i := 0; i < b.N; i++ {         replaceAtIndex1(str, replacement, index)     } }  func BenchmarkSmall2(b *testing.B) {     n := 10     str, index, replacement := generateString(n), n / 2, 'B'      b.ResetTimer()     for i := 0; i < b.N; i++ {         replaceAtIndex2(str, replacement, index)     } }  func BenchmarkMedium1(b *testing.B) {     n := 100     str, index, replacement := generateString(n), n / 2, 'B'      b.ResetTimer()     for i := 0; i < b.N; i++ {         replaceAtIndex1(str, replacement, index)     } }  func BenchmarkMedium2(b *testing.B) {     n := 100     str, index, replacement := generateString(n), n / 2, 'B'      b.ResetTimer()     for i := 0; i < b.N; i++ {         replaceAtIndex2(str, replacement, index)     } }  func BenchmarkBig1(b *testing.B) {     n := 10000     str, index, replacement := generateString(n), n / 2, 'B'      b.ResetTimer()     for i := 0; i < b.N; i++ {         replaceAtIndex1(str, replacement, index)     } }  func BenchmarkBig2(b *testing.B) {     n := 10000     str, index, replacement := generateString(n), n / 2, 'B'      b.ResetTimer()     for i := 0; i < b.N; i++ {         replaceAtIndex2(str, replacement, index)     } }  func main(){} 

shows the following results (thanks Thomasz for spotting a copypasting error):


BenchmarkSmall1-4   10000000           228 ns/op BenchmarkSmall2-4   10000000           126 ns/op BenchmarkMedium1-4    500000          2091 ns/op BenchmarkMedium2-4  10000000           190 ns/op BenchmarkBig1-4        10000        209232 ns/op BenchmarkBig2-4       500000          3629 ns/op 
like image 37
Salvador Dali Avatar answered Sep 23 '22 09:09

Salvador Dali