2012-03-10 9 views
7

Implementé una función para agrupar anagramas. En pocas palabras:Ruby forma de agrupar anagramas en matriz de cadenas

de entrada: [ 'coches', 'para', 'patatas', 'racs', 'cuatro', 'cicatriz', 'cremas', gritar ']

de salida: [ ["autos", "racs", "cicatriz"], ["cuatro"], ["para"], ["papas"], ["cremas", "gritar"]]

Me gustaria saber si hay una mejor manera de hacer esto. Realmente creo que utilicé demasiadas declaraciones de repetición: until, select, delete_if. ¿Hay alguna manera de combinar la declaración select y delete_if? Que significa, ¿los elementos seleccionados se pueden eliminar automáticamente?

Código:

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 

Gracias de antemano,

+0

posible duplicado de [Ruby Anagram Using String # sum] (http://stackoverflow.com/questions/9517745/ruby-anagram-using-stringsum) –

Respuesta

35

Al igual que:

a = ['cars', 'for', 'potatoes', 'racs', 'four','scar', 'creams', 'scream'] 
a.group_by { |element| element.downcase.chars.sort }.values 

de salida es:

[["cars", "racs", "scar"], ["for"], ["potatoes"], ["four"], ["creams", "scream"]] 

Si desea puede desactivar esta sola línea a un método, por supuesto, .

+6

Regla # 1 de la programación de Ruby: aprende los métodos de 'Enumerable' . Regla # 2: ver la Regla # 1. :-) –

+0

Es extraño que esto funcione en mi máquina, pero no en heroku! Mi sitio se cae cuando tengo esto en heroku ... – alexandrecosta

+0

Cuando ejecuto esto, solo obtengo: –

0

Usted podría utilizar la función partition en lugar de seleccionar, implementado en Enumerable. Divide las entradas dentro de la matriz de acuerdo con la función de decisión en dos matrices.

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 

(no probado)

Cuestiones relacionadas