Arrays 从序列创建子阵列

Arrays 从序列创建子阵列,arrays,ruby,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] 我想“拆开”它,这样看起来 [[5,6,7,8,9,10,11],[17], [50,51]] 实现这一目标最简单的方法是什么 arr.slice_before(&:nil?).map(&am

我有一个数组

[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]
我想“拆开”它,这样看起来

[[5,6,7,8,9,10,11],[17], [50,51]]
实现这一目标最简单的方法是什么

arr.slice_before(&:nil?).map(&:compact).reject(&:empty?)
只是出于好奇,
O(N)

我想到

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

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> 
还有两个步骤:

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]] 
编辑:多亏@Stefan,今天我学到了
chunk
处理
nil
s的新方法。正如他所建议的,我们可以将其简化为:

arr.chunk { |e| e && false }.map(&:last)
  #=> [[5, 6, 7, 8, 9, 10, 11], [17], [50, 51]]

嗯,也许他不是这么说的,但也很管用。(我的变体更像是一个令人头痛的问题。)

我喜欢。我相信我们是通过Ruby 2.2获得的。@CarySwoveland是的,它是从2.2.2获得的。在Ruby 2.3:@sawa中,我提出了一个
可枚举的#chunk_
,这将是一个受欢迎的补充。我一直在考虑增加一种方法。你能给我一个链接到你推荐的
chunk\u by
,这样我就能看到程序了吗?Cary,我打错名字了。它是
chunk\u而
。变化是巨大的。卡里和阿鲁普:
chunk\u而
slice\u的否定,当
@CarySwoveland你是对的。我走错了一步。将等待更多答案并标记最有趣的答案。我尝试了第二种方法,但没能把它变成如此优雅的形式。@CarySwoveland我添加了最复杂的方法。这是另一个好奇。如果元素是
nil
或整数,我们可以编写
arr.join(“”).strip.split(/\s{2,}/).map{s|s.split(/\s/).map(&:to_i)}
@CarySwoveland捕捉得好!稍有变化:
A.chunk{e | e&&true}.map(&:last)
enum = arr.chunk(&:nil?)
  #=> #<Enumerator: #<Enumerator::Generator:0x007fd303042440>:each> 
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]]] 
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]] 
arr.chunk { |e| e && false }.map(&:last)
  #=> [[5, 6, 7, 8, 9, 10, 11], [17], [50, 51]]