Ruby longest word in array
I built this method to find the longest word in an array, but I'm wondering if there's a better way to have done it. I'm pretty new to Ruby, and just did this as an exercise for learning the inject
method.
It returns ei开发者_JAVA百科ther the longest word in an array, or an array of the equal longest words.
class Array
def longest_word
# Convert array elements to strings in the event that they're not.
test_array = self.collect { |e| e.to_s }
test_array.inject() do |word, comparison|
if word.kind_of?(Array) then
if word[0].length == comparison.length then
word << comparison
else
word[0].length > comparison.length ? word : comparison
end
else
# If words are equal, they are pushed into an array
if word.length == comparison.length then
the_words = Array.new
the_words << word
the_words << comparison
else
word.length > comparison.length ? word : comparison
end
end
end
end
end
I would do
class Array
def longest_word
group_by(&:size).max.last
end
end
Ruby has a standard method for returning an element in a list with the maximum of a value.
anArray.max{|a, b| a.length <=> b.length}
or you can use the max_by method
anArray.max_by(&:length)
to get all the elements with the maximum length
max_length = anArray.max_by(&:length).length
all_with_max_length = anArray.find_all{|x| x.length = max_length}
Here's one using inject
(doesn't work for an empty array):
words.inject(['']){|a,w|
case w.length <=> a.last.length
when -1
a
when 0
a << w
when 1
[w]
end
}
which can be shortened to
words.inject(['']){|a,w|
[a + [w], [w], a][w.length <=> a.last.length]
}
for those who like golf.
A two liner:
vc = ['asd','s','1234','1235'].sort{|a,b| b.size <=> a.size}
vc.delete_if{|a| a.size < vc.first.size}
#Output
["1235", "1234"]
or if you want use inject, this use your idea, but its more short.
test_array.inject{ |ret,word|
ret = [ret] unless ret.kind_of?(Array)
ret << word if word.size == ret.first.size
ret = [word] if word.size > ret.first.size
ret
}
module Enumerable
def longest_word
(strings = map(&:to_s)).
zip(strings.map(&:length)).
inject([[''],0]) {|(wws, ll), (w, l)|
case l <=> ll
when -1 then [wws, ll]
when 1 then [[w], l]
else [wws + [w], ll]
end
}.first
end
end
This method only depends on generic Enumerable
methods, there's nothing Array
specific about it, therefore we can pull it up into the Enumerable
module, where it will also be available for Set
s or Enumerator
s, not just Array
s.
This solution uses the inject method to accumulate the longest strings in an array, then picks the ones with the highest length.
animals = ["mouse", "cat", "bird", "bear", "moose"]
animals.inject(Hash.new{|h,k| h[k] = []}) { |acc, e| acc[e.size] << e; acc }.sort.last[1]
This returns: ["mouse", "mouse"]
精彩评论