1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
class Array # insert i between each element in the array # this is O( 2n ) ( I think! Is it? ) as the length of the list is not needed, but we need to initially make a copy of the list def intersperse( v ) tail = [ ].replace self # we need a shallow copy first_elem = tail.first second_elem = tail[ 1 ] arr = [ ] while first_elem arr.push first_elem if second_elem arr.push v tail = tail.drop 1 first_elem = tail.first second_elem = tail[ 1 ] else break end end arr end # this is faster, but I worry that for large arrays, storing i in memory will makes this slower # Bearing that in mind, since the speed at which this goes is determined by the length of the list as well as the length of the list stored in memory ( i ) is O( n^2 ) ( again, please correct me ) def intersperse( v ) arr = [ ] i = 0 j = 0 inc_jay = lambda { j = j + 1 } while i < length arr[ j ] = self[ i ] inc_jay.call if self[ i + 1 ] arr[ j ] = v inc_jay.call end i = i + 1 end arr end end
Refactorings
No refactoring yet !
Adam
June 10, 2009, June 10, 2009 15:37, permalink
Twice the speed of your second method on my hardware, and easier on the eyes to boot. :)
1 2 3 4 5
class Array def intersperse(object) map { |element| [ element, object ] }.flatten[0..-2] end end
Martin Plöger
June 21, 2009, June 21, 2009 08:33, permalink
You could also use the alias of map: collect. Depending on your task it might read better. And you could use an exclusive Range at the end (...) instead of (..) to get rid to the superfluous last object.
1 2 3 4 5
class Array def intersperse(object) collect { |element| [ element, object ] }.flatten[0...-1] end end
Martin Plöger
June 21, 2009, June 21, 2009 17:43, permalink
This works too, but I don't like it better than the previous solution...
1 2 3 4 5
class Array def intersperse object zip(Array.new(length, object)).flatten[0...-1] end end
reima
June 25, 2009, June 25, 2009 22:45, permalink
Your usage of flatten produces wrong results when multi-dimensional arrays are involved. E.g. try [[1,2],3].intersperse([4,5]). I would've done it this way:
1 2 3 4 5 6 7 8 9 10 11
class Array def intersperse(object) result = [] for i in 0...self.size result << self[i] result << object end result.pop result end end
Intersperse is a method of the array class
Intersperse takes an object o, and returns the array ( self ), with o inserted between each element of self.