A5dbf79f90041e79418a6829d414b46e

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.

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 !

A8d3f35baafdaea851914b17dae9e1fc

Adam

June 10, 2009, June 10, 2009 15:37, permalink

1 rating. Login to rate!

Twice the speed of your second method on my hardware, and easier on the eyes to boot. :)

class Array
  def intersperse(object)
    map { |element| [ element, object ] }.flatten[0..-2]
  end
end
E8f0d6e9bc8bca695b3c5bdf75cdcc03

Martin Plöger

June 21, 2009, June 21, 2009 08:33, permalink

No rating. Login to rate!

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.

class Array
  def intersperse(object)
    collect { |element| [ element, object ] }.flatten[0...-1]
  end
end
E8f0d6e9bc8bca695b3c5bdf75cdcc03

Martin Plöger

June 21, 2009, June 21, 2009 17:43, permalink

No rating. Login to rate!

This works too, but I don't like it better than the previous solution...

class Array
  def intersperse object
    zip(Array.new(length, object)).flatten[0...-1]
  end
end
D41d8cd98f00b204e9800998ecf8427e

reima

June 25, 2009, June 25, 2009 22:45, permalink

No rating. Login to rate!

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:

class Array
  def intersperse(object)
    result = []
    for i in 0...self.size
      result << self[i]
      result << object
    end
    result.pop
    result
  end
end

Your refactoring





Format Copy from initial code

or Cancel