从序列创建子阵列

时间:2015-08-10 15:59:03

标签: arrays ruby

我的数组看起来像

[nil, nil, nil, nil, 5, 6, 7, 8, 9, 10, 11, nil, nil, nil, nil, nil, 17, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 50, 51]

我想" unflatten"它,所以它看起来像

[[5,6,7,8,9,10,11],[17], [50,51]]

实现这一目标的最简单方法是什么?

3 个答案:

答案 0 :(得分:4)

arr.slice_before(&:nil?).map(&:compact).reject(&:empty?)

出于好奇,O(N)

arr.inject([[]]) do |memo, e| 
  e ? memo.last << e : (memo << [] unless memo.last.empty?)
  memo
end

或者,现代红宝石的善良:

arr.each_with_object([[]]) do |e, memo| 
  e && memo.last << e || (memo << [] unless memo.last.empty?)
end

而且,出于好奇(这是一个笑话,请不要使用):

JSON.parse arr.to_json
              .gsub(/\D{2,}/, '],[')
              .gsub(/\A\D+/, '[[')
              .gsub(/\D+\z/, ']]')

答案 1 :(得分:3)

我想过

a.slice_when { |e1, e2| e1 != e2 && e2.nil? }.map(&:compact)
# => [[5, 6, 7, 8, 9, 10, 11], [17], [50, 51]]

答案 2 :(得分:1)

我们可以使用Enumerable#chunk

enable_shared_from_this

步骤:

arr = [nil, nil, nil, nil, 5, 6, 7, 8, 9, 10, 11, nil, nil, nil, nil, nil, 17,
       nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 50, 51]

arr.chunk(&:nil?).reject(&:first).map(&:last)
  #=> [[5, 6, 7, 8, 9, 10, 11], [17], [50, 51]] 

我们可以通过将枚举器转换为数组来检查枚举器enum = arr.chunk(&:nil?) #=> #<Enumerator: #<Enumerator::Generator:0x007fd303042440>:each> 的元素:

enum

还有两个步骤:

enum.to_a
  #=> [[true,  [nil, nil, nil, nil]],
  #    [false, [5, 6, 7, 8, 9, 10, 11]],
  #    [true,  [nil, nil, nil, nil, nil]],
  #    [false, [17]],
  #    [true,  [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]],
  #    [false, [50, 51]]] 

编辑:感谢@Stefan,今天我学到了a = enum.reject(&:first) #=> [[false, [5, 6, 7, 8, 9, 10, 11]], # [false, [17]], # [false, [50, 51]]] a.map(&:last) #=> [[5, 6, 7, 8, 9, 10, 11], [17], [50, 51]] 处理chunk的方式。正如他所建议的,我们可以将其简化为:

nil

嗯,也许这不完全是他所说的,但它的效果也一样。 (我的变体更像是一个令人头疼的问题。)