开发者

intersperse function in ruby?

开发者 https://www.devze.com 2023-01-15 17:10 出处:网络
I\'m looking for an equivalent of the haskell instersperse functionin Ruby. Basically that add something (like a separator) between each element of a list.

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("hel开发者_如何转开发lo") => [[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

)


No


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


Seems similar to zip...

Maybe something like this:

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

Usage:

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


I came here with the same question and gathered that the answer is still "no", but wanted to dream-up a more efficient implementation. Came up with these mutative and non-mutative approaches:

class Array
  def intersperse!(separator)
    (1..((size - 1) * 2)).step(2).each { |i| insert i, separator }
    self
  end

  def intersperse(separator)
    a = []
    last_i = size - 1
    each_with_index do |elem, i|
      a << elem
      a << separator unless i == last_i
    end
    a
  end
end
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号