我的数组看起来像
[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]]
实现这一目标的最简单方法是什么?
答案 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
嗯,也许这不完全是他所说的,但它的效果也一样。 (我的变体更像是一个令人头疼的问题。)