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.

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 !

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. :)

1
2
3
4
5
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.

1
2
3
4
5
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...

1
2
3
4
5
class Array
  def intersperse object
    zip(Array.new(length, object)).flatten[0...-1]
  end
end
Avatar

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:

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

Your refactoring





Format Copy from initial code

or Cancel