Ilie Soltanici
Ilie Soltanici

Reputation: 406

Finding longest word in golang

Trying to find the longest word using Go from a sentence.

At the moment I am using this method:

func longestWord(s string) string {

    newArr := strings.Split(s, " ")

    l := len(newArr[0])
    long := newArr[0]
    var result string
    // fmt.Println(long)
    for _, lenString := range newArr {

        if len(lenString) > l {
            // ll := len(lenString)
            // l := len(lenString)
            d := &l
            p := &long
            c := &result
            *d = len(lenString)
            *p = lenString
            *c = lenString
            // fmt.Println(lenString)
        } else {
            c := &result
            *c = newArr[0]
        }

    }
    return result
}

func main() {
    args := "Monday Tuesday Friday Sunday Wednesday"
    fmt.Println(longestWord(args))
}

But I'm not sure that this is the best method to achieve that. Is there any other elegant way to do that? I know that there is one more method by using sort, but I would prefer more using the way with iteration between words.

Upvotes: 5

Views: 2496

Answers (3)

icza
icza

Reputation: 417582

"Best" solution

We can even write it more compact than the other answers by taking advantage of the following:

  • using tuple assignments
  • initializing the best and its length with the zero values ("" and 0) and omitting the check for 0 words as the for range handles that properly
  • no need to store words as a local variable as it is only used in the loop

We lose nothing from readability:

func longestWord(s string) string {
    best, length := "", 0
    for _, word := range strings.Split(s, " ") {
        if len(word) > length {
            best, length = word, len(word)
        }
    }
    return best
}

Testing it:

fmt.Printf("%q\n", longestWord(""))
args := "Monday Tuesday Friday Sunday Wednesday"
fmt.Printf("%q\n", longestWord(args))

Output (try it on the Go Playground):

""
"Wednesday"

Most compact solution

Note that storing the length of the best is optional and is purely for optimization purposes, since if we have best, its length is always len(best).

Taking advantage of this, and that we can use named result parameters (and that all variables are initialized to the zero value of their types unless an initial value is provided–which for string is ""), we can even write it more compact, again losing nothing from readability:

func longestWord(s string) (best string) {
    for _, word := range strings.Split(s, " ") {
        if len(word) > len(best) {
            best = word
        }
    }
    return
}

Testing and output is the same, try it on the Go Playground. Again, in most cases this is probably slightly slower compared to when we stored the length too.

Upvotes: 7

jgulacsy
jgulacsy

Reputation: 117

I would do it like this:

func longestWord(s string) string {

newArr := strings.Split(s, " ")

longestWord := ""
longestLength := 0

    // loop through the array
    for _, word := range newArr {
        // save length of word in the actual iteration
        length := len(word)

        // if length is larger, than longest
        if length > longestLength {
            // save the new longest word
            longestWord = word
            longestLength = length
        }
    }


// return the longest word
return longestWord
}

Implementation can be found on the go playground

Upvotes: 1

eenblam
eenblam

Reputation: 438

That totally works! You could make it a bit shorter, while also using longer variable names that explain a bit more about your intention.

func longestWord(s string) string {
    words := strings.Split(s, " ")
    if len(words) == 0 {
        return ""
    }
    best := words[0]
    best_length := 0
    for _, word := range words {
        if len(word) > best_length {
            best = word
            best_length = len(word)
        }
    }
    return best
}

You could change this to track a pointer instead of the word itself if you like.

Upvotes: 4

Related Questions