3

可以说我有一个像这样的数组: ['x','cat', 'dog', 'x', 'dolphin', 'cougar', 'whale']

我不知道数组的长度或何时会出现“x”。当我到达“x”时,我想将以下元素推入一个新数组,直到到达下一个元素includes?('x')

所需的输出将是: [['cat', 'dog']['dolphin','cougar', 'whale']]

我怎样才能做到这一点?

4

5 回答 5

7

Enumerable#slice_before使这变得简单:

a = ['x','cat', 'dog', 'x', 'dolphin', 'cougar', 'whale']
a.slice_before(/\Ax\z/).map { |chunk| chunk.drop(1) }
=> [["cat", "dog"], ["dolphin", "cougar", "whale"]]
于 2013-05-10T04:26:21.317 回答
3
ar =  ['x', 'cat', 'dog', 'x', 'dolphin', 'cougar', 'whale']
p ar.chunk{|el| el == 'x'}.each_slice(2).map{|el| el.last.last}
#=> [["cat", "dog"], ["dolphin", "cougar", "whale"]]

大部分工作是消除该chunk方法不需要的副作用。

于 2013-05-09T22:53:13.827 回答
3

Enumerable#chunk是要走的路。你可以nil用来删除那些你不想要的块:

arr = ['x','cat', 'dog', 'x', 'dolphin', 'cougar', 'whale']

arr.chunk{ |e| e != 'x' || nil }.map(&:last)
#=> [["cat", "dog"], ["dolphin", "cougar", "whale"]]
于 2013-05-10T01:16:03.773 回答
2

Good oldEnumerable#reduce对很多事情都很方便:

def split_array_by_item(array, item)
  array.reduce([]) do |memo, x|
    memo.push([]) if (x == item) || memo.empty?
    memo[-1].push(x) unless x == item
    memo
  end
end

a = ['x', 'cat', 'dog', 'x', 'dolphin', 'cougar', 'whale'] 
split_array_by_item(a, 'x') # => [["cat", "dog"], ["dolphin", "cougar", "whale"]] 

[编辑]还有:

def split_array_by_item(array, item)
  array.chunk{|x|x==item}.reject(&:first).map(&:last)
end
于 2013-05-09T22:45:55.757 回答
0

从 Ruby 2.0 开始,一个不错的解决方案是slice_before方法或从 2.2开始的slice_when方法:

然而,我们需要为每个生成的数组删除第一个元素“x”:

ary =  ['x', 'cat', 'dog', 'x', 'dolphin', 'cougar', 'whale']

ary.slice_before{|e| e=='x'}.map{|t| t.drop(1)}

#==> [["cat", "dog"], ["dolphin", "cougar", "whale"]]

ary.slice_when{|i,j| j=='x'}.map{|t| t.drop(1)}

#==> [["cat", "dog"], ["dolphin", "cougar", "whale"]]
于 2016-03-16T20:54:09.320 回答