tags:

views:

80

answers:

3

Hi I'm looking for an equivalent of the haskell instersperse function in Ruby. Basically that add something (like a separator) between each element of a list.

intersperse(nil, [1,2,3]) => [1,nil,2,nil,3,nil,4].

I'm not asking for any code (I can do it , and I'd probably have done it before you read the question). I'm just wondering if a such function already exists on the standard Ruby platform.

update

I'm not asking for any code, and especially ones using flatten, as that doesn't work (flatten does not only flat one level but all). I gave the example [1,2,3] just as example, but it should work with

 [[1,2],[3,4]].interperse("hello") => [[1,2], "hello", [3,4]]

(Please don't send me any code to make that it work , I have it already

class Array
  def intersperse(separator)
    (inject([]) { |a,v|  a+[v,separator] })[0...-1]
  end
end

)

+1  A: 

No

gnibbler
Would adding a full stop make the answer too verbose? :)
Andrew Grimm
+1  A: 

Seems similar to zip...

Maybe something like this:

class Array
  def intersperse(item)
    self.zip(item).flatten[0...-1]
  end
end

Usage:

[1,2,3].intersperse([nil]) #=> [1, nil, 2, nil, 3]
Mark Thomas
+2  A: 

No, not that I know of. But you can always check yourself.

The only similar method (by the way: Ruby is an object-oriented language, there is no such thing as a "function" in Ruby) is Array#join, which maps the elements to strings and interperses them with a separator. Enumerable#intersperse would basically be a generalization of that.

Like you said, it's trivial to implement, for example like this:

module Enumerable
  def intersperse(obj=nil)
    map {|el| [obj, el] }.flatten(1).drop(1)
  end
end

or this:

module Enumerable
  def intersperse(obj=nil)
    drop(1).reduce([first]) {|res, el| res << obj << el }
  end
end

Which would then make Array#join simply a special case:

class Array
  def join(sep=$,)
    map(&:to_s).intersperse(s ||= sep.to_str).reduce('', :<<)
  end
end
Jörg W Mittag
I love how the question explicitly states *not* to post an implementation, and *only* answer the question whether such a method already exists, and all three answers ignore the request and two out of three don't even answer the question :-)
Jörg W Mittag
Because when people ask questions like this, they never really seem happy with a "No" answer - and besides, it's not enough characters :)
gnibbler
By offering an alternative, it is an implied "no". But what's the fun in answering a yes/no question that as you say, can be checked in a few seconds?
Mark Thomas
just out of curiosity, if ruby doesn't have functions, whats a lambda?
Matt Briggs
@jorg: I love it too. see my update
mb14
@gnibbler, i would have been happy with a "No". Guess I have to answer it mylself and accept my own no ;-)
mb14
@mark it could be check in a few second , only if the answer is yes. No finding it in the doc doesn't mean anything exist.
mb14
@mb14, ok I updated my answer :)
gnibbler
@Jörg: Do you think there should be a feature request for intersperse?
Andrew Grimm
@Andrew Grimm: I'm thinking about it. I've also been looking at `Enumerable#scan`. In fact, I may just read the entire [ScalaDocs](http://Scala-Lang.Org/archives/downloads/distrib/files/nightly/docs/library/scala/collection/immutable/Traversable.html) and [Haddocks](http://Haskell.Org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Data-List.html) for Scala's and Haskell's collections libraries, and check out which of the missing functionality makes sense for Ruby. We already have Scala's `flatMap` in Ruby 1.9.2 as `Enumerable#flat_map` / `Enumerable#concat_collect`.
Jörg W Mittag
`span`, `splitAt`, `unzip`, `unfold`, `intercalate`, `subsequences`, `inits`, `tails`, `stripPrefix`, `isPrefixOf`, `isSuffixOf`, `isInfixOf` all look pretty nice.
Jörg W Mittag
@mb14: There's this: http://Prelude.RubyForge.Org/, but it looks abandoned.
Jörg W Mittag
@Jorg: That's great, I'm not sure my boss (and the team) will be happy if I start using it.
mb14