Qual è il modo migliore per dividere una stringa per ottenere tutte le sottostringhe di Ruby?

Ad esempio, le parole “stack”, voglio ottenere un array come:

['s', 'st', 'sta', ... 'stack', 't', 'ta', ... , 'c', 'ck', 'k'] 

L’ho fatto con questo codice:

 def split_word(str) result = [] chas = str.split("") len = chas.size (0..len-1).each do |i| (i..len-1).each do |j| result.push(chas[i..j].join) end end result.uniq end 

C’è un modo migliore e pulito per farlo? Grazie.

 def split_word s (0..s.length).inject([]){|ai,i| (1..s.length - i).inject(ai){|aj,j| aj << s[i,j] } }.uniq end 

E puoi anche considerare di utilizzare Set anziché Array per il risultato.

PS: Ecco un'altra idea, basata sul prodotto array:

 def split_word s indices = (0...s.length).to_a indices.product(indices).reject{|i,j| i > j}.map{|i,j| s[i..j]}.uniq end 

Scriverei:

 def split_word(s) 0.upto(s.length - 1).flat_map do |start| 1.upto(s.length - start).map do |length| s[start, length] end end.uniq end groups = split_word("stack") # ["s", "st", "sta", "stac", "stack", "t", "ta", "tac", "tack", "a", "ac", "ack", "c", "ck", "k"] 

Di solito è più chiaro e più compatto usare map (funzionale) invece del pattern init vuoto + each + append + return (imperativo).

Non pensarlo.

Ecco la mia versione tentata:

 def split_word(str) length = str.length - 1 [].tap do |result| 0.upto(length) do |i| length.downto(i) do |j| substring = str[i..j] result << substring unless result.include?(substring) end end end end 
 def substrings(str) output = [] (0...str.length).each do |i| (i...str.length).each do |j| output << str[i..j] end end output end 

questa è solo una versione ripulita del tuo metodo e funziona con meno passaggi =)

 def substrings(str) (0...str.length).map do |i| (i...str.length).each { |j| str[i..j]} end end 

Solo un altro modo per farlo, che mi sembra un po ‘più chiaro.

Molto più tardi, ma questo è ciò che ho ottenuto riformattando il tuo codice un po ‘.

 def substrings(string) siz = string.length answer = [] (0..siz-1).each do |n| (n..siz-1).each do |i| answer << string[n..i] end end answer end