Reputation: 75
I would like to remove an element from the slice in place. But when I do this I end up producing two empty elements in the underlying array. I already searched here, here
package main
import "fmt"
//String remove adjacent duplicates from a string array
func rmDup(str []string) []string {
for i := 1; i < len(str); i++ {
if str[i] == str[i-1] {
copy(str[i:], str[i+1:])
str[len(str)-1] = ""
str = str[:len(str)-1]
}
}
return str
}
func main() {
str := []string{"dog", "cat", "cat", "mouse", "mouse", "zebra", "zebra"}
fmt.Println(str)
newstr := rmDup(str)
fmt.Println(str)
fmt.Println(newstr)
fmt.Println(len(str), cap(str), "final")
fmt.Println(len(newstr), cap(newstr), "final")
}
Is there any way that str in main can return the size and capacity defined in rmDup()
Upvotes: 2
Views: 4167
Reputation: 75
It turned out that I was able to find the answer myself. Since the Go language performs function calls by value it is impossible to change a slice declared in another scope, except using pointers.
package main
import "fmt"
//String remove adjacent duplicates from a string array
func rmDup(str *[]string) []string {
var s = *str
for i := 1; i < len(s); i++ {
if s[i] == s[i-1] {
copy(s[i:], s[i+1:])
s[len(s)-1] = ""
s = s[:len(s)-1]
}
}
*str = s
return s
}
func main() {
str := []string{"dog", "cat", "cat", "mouse", "mouse", "zebra",
"zebra"}
fmt.Println(str)
newstr := rmDup(&str)
fmt.Println(str)
fmt.Println(newstr)
fmt.Println(len(str), cap(str), "final")
fmt.Println(len(newstr), cap(newstr), "final")
}
Output:
[dog cat cat mouse mouse zebra zebra]
[dog cat mouse zebra]
[dog cat mouse zebra]
4 7 final
4 7 final
Upvotes: 3
Reputation: 166569
Is there any way that
str
inmain
can return the size and capacity defined inrmDup()
?
For example,
package main
import "fmt"
//String remove adjacent duplicates from a string array
func rmDup(str []string) []string {
for i := 1; i < len(str); i++ {
if str[i] == str[i-1] {
copy(str[i:], str[i+1:])
str[len(str)-1] = ""
str = str[:len(str)-1]
}
}
return str
}
func main() {
str := []string{"dog", "cat", "cat", "mouse", "mouse", "zebra", "zebra"}
fmt.Println(len(str), cap(str), str)
str = rmDup(str)
fmt.Println(len(str), cap(str), str)
}
Output:
7 7 [dog cat cat mouse mouse zebra zebra]
4 7 [dog cat mouse zebra]
i meant in place without the function
rmDup()
having to return anything.
For example,
package main
import "fmt"
//String remove adjacent duplicates from a string array
func rmDup(str *[]string) {
s := *str
for i := 1; i < len(s); i++ {
if s[i] == s[i-1] {
copy(s[i:], s[i+1:])
s[len(s)-1] = ""
s = s[:len(s)-1]
}
}
*str = s
}
func main() {
str := []string{"dog", "cat", "cat", "mouse", "mouse", "zebra", "zebra"}
fmt.Println(len(str), cap(str), str)
rmDup(&str)
fmt.Println(len(str), cap(str), str)
}
Output:
7 7 [dog cat cat mouse mouse zebra zebra]
4 7 [dog cat mouse zebra]
Upvotes: 2