Home > Software design >  how to invoke a function from the result of another function
how to invoke a function from the result of another function

Time:11-13

package main

import "fmt"

func Reverse(str string) string {
    r := ""
    for i := len(str) - 1; i >= 0; i-- {
        r  = string(str[i])
        // fmt.Println(r)
    }
    return r 
}

func Generate(str string) string {
    str = Reverse(str)
    // vowel := ""
    for _, rne := range str {
        if rne == 'a' {
            str  = "A"

        }
        if rne == 'e' {
            str  = "E"

        }
        if rne == 'i' {
            str  = "I"

        }
        if rne == 'o' {
            str  = "O"

        }
        if rne == 'u' {
            str  = "U"

        }
    }

    return Reverse(str) 
}
func main() {
    fmt.Println(...("haigolang123"))
}

This program will accept a logic from the previous function, then combine it with the next function. I wondering how to invoke a function from the result of another function. expect output is "321gnAlOgIAh"

CodePudding user response:

I didn't get why you are trying to reverse the string twice if your input is haigolang123 and expected output is 321gnAlOgIAh. Let's refactor step by step.

  1. For vowels, if all you needed to do is convert lower case to upper, you can direct subtract number 32 from rune (since 'a'=97 & 'A'=65). So, use a function to common out the check.
func in(c rune, list []rune) bool {
    for _, l := range list {
        if c == l {
            return true
        }
    }

    return false
}

This can check as follows:

vowelsLower := []rune{'a', 'e', 'i', 'o', 'u'}
# Some code here
if in(c, vowelsLower) {
    result  = string(c-32)
}
  1. There are many ways to append strings, refer here when working particularly with strings. However, we are working with runes. It is easier to append it to a byte slice. Looking at the bigger picture, []byte can be directly converted to string when needed.
var result []byte
# Some code here
if in(c, vowelsLower) {
    result = append(result, byte(c-diff))
}

While returning,

return string(result)

This is your code with these changes.

  1. Additionally, why to iterate twice (once in Generate, and again in Reverse). Try reverse iterating and do the vowel case switching. The noticeable difference of this approach is it uses bytes directly.

Range over string gives rune. Slicing the string gives byte. Of course they can be typecasted from one another.

Since we were already using bytes in previous approach, the code looks like this.

Happy coding!!

CodePudding user response:

In Go, write

package main

import "fmt"

func toUpper(r rune) rune {
    switch r {
    case 'a', 'e', 'i', 'o', 'u':
        r &= 0b1101_1111
    }
    return r
}

func Generate(s string) string {
    g := []rune(s)
    for i, j := 0, len(g)-1; i <= j; i, j = i 1, j-1 {
        g[i], g[j] = toUpper(g[j]), toUpper(g[i])
    }
    return string(g)
}

func main() {
    s := "haigolang123"
    fmt.Printf("%q\n", s)
    g := Generate(s)
    fmt.Printf("%q\n", g)
}

https://go.dev/play/p/pGRas6qsi8O

"haigolang123"
"321gnAlOgIAh"

Go is designed for efficient solutions.

In Go, strings are immutable. concatenating strings a and b creates a new string of length len(a) len(b) and copies both a and b to the new string. It can get expensive.

Testing characters for all the vowels, even after you have matched one, is unnecessary.

Refactor your functional decomposition of Generate to include reversing a string while using a toUpper function for vowels.

  •  Tags:  
  • go
  • Related