Ruby самое длинное слово в массиве
Я построил этот метод, чтобы найти самое длинное слово в массиве, но мне интересно, есть ли лучший способ сделать это. Я довольно новичок в Ruby, и просто сделал это как упражнение для изучения inject
метод.
он возвращает либо самое длинное слово в массиве, либо массив равных длинных слов.
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
6 ответов
Ruby имеет стандартный метод для возврата элемента в списке с максимальным значением.
anArray.max{|a, b| a.length <=> b.length}
или вы можете использовать метод max_by
anArray.max_by(&:length)
чтобы получить все элементы с максимальной длиной
max_length = anArray.max_by(&:length).length
all_with_max_length = anArray.find_all{|x| x.length = max_length}
здесь один, используя inject
(не работает для пустого массива):
words.inject(['']){|a,w|
case w.length <=> a.last.length
when -1
a
when 0
a << w
when 1
[w]
end
}
который можно сократить до
words.inject(['']){|a,w|
[a + [w], [w], a][w.length <=> a.last.length]
}
для тех, кто любит гольф.
два вкладыша:
vc = ['asd','s','1234','1235'].sort{|a,b| b.size <=> a.size}
vc.delete_if{|a| a.size < vc.first.size}
#Output
["1235", "1234"]
или если вы хотите использовать inject, это использует вашу идею, но более короткую.
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
этот метод зависит только от generic Enumerable
методы, нет ничего Array
специфическое об этом, поэтому мы можем вытащить его в Enumerable
модуль, где он будет доступен для Set
или Enumerator
s, а не просто Array
s.
Это решение использует метод inject для накопления самых длинных строк в массиве, а затем выбирает строки с наибольшей длиной.
animals = ["мышь", "кошка", "птица", "медведь", "лось"]
животные.inject(хэш.новый {/h, k / h[k] = []}) {/acc, e / acc[e.size]
Это возвращает: ["мышь", "мышь"]