问题
I implemented a function to group anagrams. In a nutshell:
input: ['cars', 'for', 'potatoes', 'racs', 'four','scar', 'creams', scream']
output: [["cars", "racs", "scar"], ["four"], ["for"], ["potatoes"],["creams", "scream"]]
I would like to know if there is a better way to do this.
I really think I used too much repetition statements: until
, select
,
delete_if
.
Is there any way to combine the select
and delete_if
statement? That
means, can selected items be automatically deleted?
Code:
def group_anagrams(words)
array = []
until words.empty?
word = words.first
array.push( words.select { |match| word.downcase.chars.sort.join.eql?(match.downcase.chars.sort.join ) } )
words.delete_if { |match| word.downcase.chars.sort.join.eql?(match.downcase.chars.sort.join ) }
end
array
end
Thanks in advance,
回答1:
Like that:
a = ['cars', 'for', 'potatoes', 'racs', 'four','scar', 'creams', 'scream']
a.group_by { |element| element.downcase.chars.sort }.values
Output is:
[["cars", "racs", "scar"], ["for"], ["potatoes"], ["four"], ["creams", "scream"]]
If you want to you can turn this one-liner to a method of course.
回答2:
You could use the partition
function instead of select, implemented in Enumerable. It splits the entries within the array according to the decision-function into two arrays.
def group_anagrams(words)
array = []
until words.empty?
word = words.first
delta, words = words.partition { |match| word.downcase.chars.sort.join.eql?(match.downcase.chars.sort.join ) } )
array += delta
end
array
end
(untested)
来源:https://stackoverflow.com/questions/9646995/ruby-way-to-group-anagrams-in-string-array