2013-05-09 52 views
3

可以說我有一個數組,像這樣: ['x','cat', 'dog', 'x', 'dolphin', 'cougar', 'whale']切片數組元素時達到

我不知道數組或當「X」會發生的長度。當我到達'x'時,我想將下列元素推入新的數組中,直到我到達下一個元素includes?('x')

所需的輸出將是: [['cat', 'dog']['dolphin','cougar', 'whale']]

我怎樣才能做到這一點?

+2

啊,親愛的SO'你到目前爲止試過了什麼?'。 試了很多,但它沒有讓我遠...不知道如何解決這個問題。 IM STUCK :( – Snarf 2013-05-09 22:39:05

+0

如果一行中有兩個「x」或結尾是「x」,該怎麼辦?有什麼行爲?忽略或者有一個空的'[]'? – 2013-05-10 14:08:38

回答

2

好老Enumerable#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 
+0

先生,我欠你一杯啤酒。 – Snarf 2013-05-09 22:53:05

+3

@Snarf:我接受你的報價! – maerics 2013-05-09 22:53:18

+2

@Snarf我回答了,我也可以有嗎? – squiguy 2013-05-09 22:54:22

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

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"]] 
+0

酷。 :'arr.chunk {| e | true if e!='x'} .map(&:last)''你可以用任何真理替換'true'。 – 2014-09-26 04:48:01

+0

這個版本非常明確:'arr。 chunk {| e | e =='x'?:_separator::payload} .map(&:last)' – 2014-09-26 04:50:12

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"]] 
+0

+1,我希望有人會提到'slice_before'。 – 2013-05-10 04:34:22

0

由於紅寶石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"]]