红宝石中的穿插功能?

时间:2010-09-09 11:22:12

标签: ruby

我正在寻找相当于Ruby中的haskell instersperse函数。基本上,在列表的每个元素之间添加一些东西(比如分隔符)。

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

我不是要求任何代码(我可以做到,我可能在你阅读这个问题之前已经完成了)。我只是想知道标准Ruby平台上是否已经存在这样的函数。

更新

我不是要求任何代码,特别是那些使用flatten的代码,因为它不起作用(flatten不仅平坦一个级别而且全部)。 我给出了示例[1,2,3]作为示例,但它应该与

一起使用
 [[1,2],[3,4]].interperse("hello") => [[1,2], "hello", [3,4]]

(请不要向我发送任何代码以使其有效,我已经有了

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

4 个答案:

答案 0 :(得分:9)

没有

答案 1 :(得分:6)

不,不是我所知道的。但你总是可以check yourself

唯一类似的方法(顺便说一句:Ruby是一种面向对象的语言,Ruby中没有“函数”这样的东西)是Array#join,它将元素映射到字符串并用它们交织它们分隔符。 Enumerable#intersperse基本上是对此的概括。

就像你说的那样,实施它是微不足道的,例如:

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

或者这个:

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

这会使Array#join只是一个特例:

class Array
  def join(sep=$,)
    map(&:to_s).intersperse(s ||= sep.to_str).reduce('', :<<)
  end
end

答案 2 :(得分:2)

似乎与zip相似......

也许是这样的:

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

用法:

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

答案 3 :(得分:0)

我带着同样的问题来到这里并得出结论,答案仍然是“否”,但想想出一个更有效的实施方案。提出了这些可变和非可变方法:

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