Daniel Rangel
Daniel Rangel

Reputation: 75

Is it possible for a function to change the size of a slice of string array declared elsewhere? golang

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

Answers (2)

Daniel Rangel
Daniel Rangel

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

peterSO
peterSO

Reputation: 166569

Is there any way that str in main can return the size and capacity defined in rmDup()?

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

Related Questions