On 09.05.2007 21:02, Drew Olson wrote: > All - > > I've been using ruby for quite some time and I'm only beginning to look > at python. I really like the way ruby flows as compared to python and I > can't see myself getting pulled away from ruby. However, there is one > thing I like about python, and that is the generators. What is the best > way to translate the following code into ruby? Assume word is some > string and letters is a string of all the characters a..z: > > [word[0:i]+c+word[i+1:] for i in range(len(word)) for c in letters] > > This is all based on trying to efficiently rewrite > http://norvig.com/spell-correct.html in ruby. Essentially what this code > does is get the array of words resulting from inserting every character > at every possible position in the given word. I find it pretty succinct, > but I know ruby can do better! I've come up with two ways to do this in > ruby, but neither seems to "click" with me: > > (0...word.size).inject([]) do |words,i| > letters.split('').each do |c| > words << word[0...i]+c+word[i..-1] > end > words > end > > OR > > (0...words.size).map do |i| > letters.split('').map do |c| > word[0...i]+c+word[i..-1] > end > end.flatten > > Any advice? Currenty, I'm using the first approach and it's sloooooow > (I'm assuming inject has high overhead). Since you are splitting letters all the time, I'd start with pulling out this from the loop. So you could do LETTERS = "a".."z" Then, for efficiency reasons, I would not construct the whole thing in memory but create an Enumerable class for it WordGen = Struct.new(:word) do include Enumerable def each word.size.times do |idx| WordGen::LETTERS.each do |chr| yield word[0...idx] << chr << word[idx..-1] end end self end def to_a map {|x|x} end end WordGen::LETTERS = "a".."z" Note also, that you can use "<<" with substrings without affecting the original string. "<<" is more efficient than "+". Now you can do wg = WordGen.new "foobar" wg.each {|w| puts w} array = wg.to_a # etc. Kind regards robert