简体   繁体   English

如何使用分隔符将Ruby数组拆分为不等大小的子数组

[英]How to split a Ruby array into subarrays of unequal size using a delimiter

I have the following array: 我有以下数组:

arr = [0, 1, 1, 2, 3, 1, 0, 0, 1]

Without changing the order of the values, I need to subdivide arr into smaller arrays at every occurrence of 0 , such that the result would be: 在不改变值的顺序的情况下,我需要在每次出现0arr细分为更小的数组,这样结果将是:

arr = [ [0, 1, 1, 2, 3, 1], [0], [0, 1] ]

If arr were a string, I could use .split("0") and then prepend the delimiter to each subarray. 如果arr是一个字符串,我可以使用.split("0")然后将分隔符添加到每个子数组。 What would be the most efficient equivalent to .split() in plain Ruby for arrays? 普通Ruby中数组中.split()最有效的等价物是什么?

Enumerable#slice_before does this exact thing: Enumerable#slice_before做了这件事:

arr = [0, 1, 1, 2, 3, 1, 0, 0, 1]
p arr.slice_before(0).to_a
# => [[0, 1, 1, 2, 3, 1], [0], [0, 1]]

See it on repl.it: https://repl.it/FBhg 看到它在repl.it: https://repl.it/FBhg

Since ActiveSupport defines an Array#split method in Ruby , we can use it as a starting point: 由于ActiveSupport在Ruby中定义了一个Array#split方法 ,我们可以将它作为一个起点:

class Array
  def split(value = nil)
    arr = dup
    result = []
    if block_given?
      while (idx = arr.index { |i| yield i })
        result << arr.shift(idx)
        arr.shift
      end
    else
      while (idx = arr.index(value))
        result << arr.shift(idx)
        arr.shift
      end
    end
    result << arr
  end
end

# then, using the above to achieve your goal:
arr = [0, 1, 1, 2, 3, 1, 0, 0, 1]
arr.split(0).map { |sub| sub.unshift(0) }
# => [[0], [0, 1, 1, 2, 3, 1], [0], [0, 1]] 

Note that your verbal phrasing of the algorithm (split and prepend) is what is happening here, but your expected output is different (there's an additional zero because of the way split works). 请注意,您对算法的语言短语(分割和前置)就是这里发生的事情,但您的预期输出是不同的(由于split工作方式,还有一个额外的零)。

Do you want to split before each zero ? 你想在每个零之前拆分吗? For this you could use slice_before . 为此你可以使用slice_before

Do you want to split but drop empty arrays ? 你想分裂但删除空数组吗? This could be done with a quick compact before prepending, but you would lose the [0] subarray. 这可以在前置之前用快速compact完成,但是你会失去[0]子阵列。

Do you want to split but drop the first element if empty ? 你想拆分但是如果空的话就放下第一个元素吗?

Do you want to split on /0+/ ? 你想拆分/0+/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM