Write a method that takes in a string and returns the longest word in the string

Write a method that takes in a string and returns the longest word in the string.

def longest_word(sentence)
  #arr=[]
  arr=sentence.split(" ")
  i=0
  var=""
  while(i<arr.length)
    if var<arr[i]
      var=arr[i]
      i+=1
    end
    return var
  end
end

Here’s my implementation.

def longest_word(sentence)
  length = ->word1, word2{ word1.length <=> word2.length }
  sentence.split(/ /).max(&length)
end

longest_word "The rain in Spain stays mainly in the plain"
# => "mainly"


It looks great the prob I don’t understand it being a total newbie
Is there any way you can correct mine so that it works?
Thanks

Okay; the problem lies in this area.

while(i<arr.length)
  if var<arr[i]
    var=arr[i]

The if var<arr[i] isn’t checking var.length or arr[i].length

arr[i] evaluates to the string of each word. You need to call .length on it if you want the length value to compare.

var itself is also just a string. You need to do the same for it.

At first glance it looks like fixing this will make it work, but you might want to check and make sure every word is being evaluated when you do things like this in the future. For that I recommend writing

puts arr[1]

somewhere in the while loop and see what prints out on the command line. You can use puts to print most anything in Ruby to see what you’re working with.

You’re also returning from inside the loop, so it will return the first
word, always

1 Like

@danielpclark Why have that lambda in there?

Can’t you just do:

def longest_word(sentence)
  sentence.split(" ").max_by(&:size)
end
2 Likes

Thank you, Sir and everybody else for your help.
I was finally able to get it to work according to my logic and although I’m not very sure if it checks for everything it needs to check - it does return true on all tests.
So happy camper here :slight_smile:

def longest_word(sentence)
  temp=sentence.split(" ")
  i=0 
  bigW=nil 
  while(i<temp.length)
    currentW=temp[i]
    if bigW==nil
      bigW=temp[i]
    elsif bigW.length<currentW.length
      bigW=currentW
    end 
    i+=1
  end 
  return currentW
end
1 Like

It’s been a while since I’ve done anything with max. I had completely forgotten about max_by.

As a sidenote, max also takes a block and yields pairs of elements:

sentence.split(" ").max { |word1, word2| word1.size <=> word2.size }

would also give the correct result.

I don’t usually use max_by either, but it, and min, has the same interface as sort and sort_by, which I use quite often.

1 Like

Yeah. I kind of wanted to end with a conclusive line that read more like English. Which is why I went with the stabby lambda.

@marin-cabac: Just, so that you don’t feel left out of @danielpclark and my conversation, I’ll try and comment a bit on your final code-snippet.

I know that you’re a beginner in the world of Ruby, so I’ll go through the stuff one at a time.

  • First off, to ease your readability, I propose that you begin to add spaces before and after =, <, >, etc.

  • Second, we very seldom use while and for loops in Ruby code. Usually we use the each on arrays instead. Say you want to just print out each element in an array. Here’s what that looks like, first with while, then for, and finally the “correct way” with each:

      words = ["This", "is", "a", "sentence"]
      i = 0
      current_word = nil
      while i < words.size
        current_word = words[i]
        puts current_word # => this outputs the word
        i += 1
      end
    

Using for we can get rid counting i ourselves:

    words = ["This", "is", "a", "sentence"]
    current_word = nil
    for i in 0..words.size-1
      current_word = words[i]
      puts current_word # => this outputs the word
    end

And finally, we can do it with the each method on the array, which is the “proper” way of doing it in Ruby:

   words = ["This", "is", "a", "sentence"]
   words.each do |current_word|
     puts current_word # => this outputs the word
   end

The each yields each element of the array to the variable between the two ||. Had we wanted the index for something, we could use each_with_index and then have both |current_word, i| in the vertical bars instead.

I hope that clears it up a bit regarding the loop constructs? Once you find yourself familiar with each you can look into other methods, like sort, max, and so on as well.

1 Like