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:]}, "") }
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.
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.
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.
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.
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With