Benjamints
Benjamints

Reputation: 849

Find the last occurence of a string being a certain length

I know there is a method to find the largest string in an array

def longest_word(string_of_words)
  x = string_of_words.split(" ").max_by(&:length)
end

However, if there are multiple words with the longest length, how do i return the last instance of the word with the longest length? Is there a method and do I use indexing?

Benjamin

Upvotes: 1

Views: 112

Answers (6)

Sagar Pandya
Sagar Pandya

Reputation: 9497

You can use inject which will replace the maximum only if (via <=) it's matched or improved upon. By default inject takes the first element of its receiver.

str.split.inject { |m,s| m.size <= s.size ?  s : m }

Upvotes: 1

Ursus
Ursus

Reputation: 30056

What if we took advantage of reverse?

"asd qweewe lol qwerty df qwsazx".split.reverse_each.max_by(&:length)
=> "qwsazx"

Upvotes: 3

Cary Swoveland
Cary Swoveland

Reputation: 110675

There's no need to convert the string to an array.

def longest_word(str)
  str.gsub(/[[:alpha:]]+/).
      each_with_object('') {|s,longest| longest.replace(s) if s.size >= longest.size}
end

longest_word "Many dogs love to swim in the sea"
  #=> "swim"

Two points.

  • I've used String#gsub to create an enumerator that will feed words to Enumerable.#each_with_object. The string argument is not modified. This is an usual use of gsub that I've been able to use to advantage in several situations.
  • Within the block it's necessary to use longest.replace(s) rather than longest = s. That's because each_with_object returns the originally given object (usually modified by the block), but does not update that object on each iteration. longest = s merely returns s (is equivalent to just s) but does not alter the value of the block variable. By contrast, longest.replace(s) modifies the original object.

With regard to the second of these two points, it is interesting to contrast the use of each_with_object with Enumerable#reduce (aka inject).

  str.gsub(/[[:alpha:]]+/).
      reduce('') {|longest,s| s.size >= longest.size ? s : longest }
    #=> "swim"

Upvotes: 0

sawa
sawa

Reputation: 168091

max_by.with_index{|e, i| [e, i]}

Upvotes: 0

Gagan Gami
Gagan Gami

Reputation: 10251

can do this way also:

 > "asd qweewe lol qwerty df qwsazx".split.sort_by(&:length).last
 #=> "qwsazx"

Note: You can split words and sort by length in ascending(default) order and take the last word

Upvotes: 1

Eric Duminil
Eric Duminil

Reputation: 54223

Simply reverse your words array before applying max_by.

The first longest word from the reversed array will be the last one in your sentence.

Upvotes: 2

Related Questions