2013-07-24 44 views
0

例如我有一個數組如何在Ruby中匹配條件時在數組內創建數組?

g = [0,0,0,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,0,1,1,1] 

而作爲一個結果,我需要

f = [0,0,0,[1,1,1],0,[1,1],0,0,1,0,0,[1,1,1,1],0,0,0,[1,1,1]] 

需要加入的元素(1)僅當它們出現在序列中的兩個或更多次。

+0

所以,你在哪裏卡住了? –

+0

只是不知道該怎麼做.. – DenisKo

+0

好吧,這裏有一個想法:通過源數組循環並檢查元素。如果它不是'1',則將其附加到結果數組中。如果它是'1',則將其追加到臨時數組中。如果它不是'1',則將該臨時數組附加到結果數組。 –

回答

0

實施塞爾吉奧Tulentsev

g = [0,0,0,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,0,1,1,1] 
f = [] 
ones = [] 
g.each { |x| 
    if x == 1 
    ones << x 
    else 
    if ones.size > 1 
     f << ones 
    elsif ones.size == 1 
     f += ones 
    end 
    ones = [] 
    f << x 
    end 
} 
if ones.size > 1 
    f << ones 
elsif ones.size == 1 
    f += ones 
end 

UPDATE的想法

替代

g = [0,0,0,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,0,1,1,1] 
f = [] 
g.each { |x| 
    if x == 1 
    f << [] if ! f.last.is_a? Array 
    f.last << x 
    else 
    f << x 
    end 
} 
f.each_with_index { |x,i| f[i] = 1 if x == [1] } 
1
g.inject([]) do |ary, i| 
    if i == 0 or ary.last == 0 
    ary << i 
    else 
    ary[-1] = Array(ary.last) << i 
    ary 
    end 
end 

=> [0, 0, 0, [1, 1, 1], 0, [1, 1], 0, 0, 1, 0, 0, [1, 1, 1, 1], 0, 0, 0, [1, 1, 1]] 

這應該是O(n)的運行時間。

FYI:Array(thing)在數組([thing])中包裝thing,除非它已經是一個數組。

+0

對不起,在第一個地方,我沒有包括你的一個基準報告...謝謝你加入.. * + 1 *也給你.. :)) –

+0

不要對不起!我自己添加時沒有問題;) – tessi

1

Enumerable#chunk將是一個很好的選擇。

g = [0,0,0,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,0,1,1,1] 
p g.chunk{|i| i == 0}.to_a 
# >> [[true, [0, 0, 0]], [false, [1, 1, 1]], [true, [0]], 
# [false, [1, 1]], [true, [0, 0]], [false, [1]], 
# [true, [0, 0]], [false, [1, 1, 1, 1]], 
# [true, [0, 0, 0]], [false, [1, 1, 1]]] 
ar = g.chunk{|i| i == 0}.each_with_object([]) do |(e1,e2),a| 
    (!e1 && e2.size > 1) ? a.concat([e2]) : a.concat(e2) 
end 
p ar 
# >> [0, 0, 0, [1, 1, 1], 0, [1, 1], 0, 0, 1, 0, 0, 
# [1, 1, 1, 1], 0, 0, 0, [1, 1, 1] 

基準

require 'benchmark' 

g = [0,0,0,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,0,1,1,1] 
n = 1000000 
Benchmark.bm(15) do |x| 
    x.report('stefan') { n.times { g.chunk{ |e| e }.flat_map { |a, b| a == 0 || b.length == 1 ? b : [b] } } } 
    x.report('priti') { n.times { g.chunk{|i| i == 0}.each_with_object([]){|(e1,e2),a| (!e1 && e2.size > 1) ? a.concat([e2]) : a.concat(e2)} } } 
    x.report('tessi') { n.times { g.inject([]) { |ary, i| (i == 0 or ary.last == 0) ? ary << i : (ary[-1] = Array(ary.last) << i); ary }}} 
end 

         user  system  total  real 
stefan   11.860000 0.000000 11.860000 (11.890553) 
priti   13.360000 0.000000 13.360000 (13.406585) 
tessi    5.650000 0.000000 5.650000 ( 5.666377) 
+0

將我的實現添加到您的基準測試中,希望對您有用。 – tessi

+0

@tessi我沒有問題..你可以添加它..請繼續.. :) –

3

這會工作,太:

g.chunk{ |e| e }.flat_map { |a, b| a == 0 || b.length == 1 ? b : [b] } 
#=> [0, 0, 0, [1, 1, 1], 0, [1, 1], 0, 0, 1, 0, 0, [1, 1, 1, 1], 0, 0, 0, [1, 1, 1]] 
+0

正如你已經減少它,那麼爲什麼不'g.chunk {| e | e} .flat_map {| a,b |一個== 0 || b.length == 1? b:[b]}? :)) –

+1

@Priti謝謝你的指針,我以爲'flat_map'會變平'[b]' – Stefan

+0

* + 1 * ..'chunk'是處理這個問題的好方法..它會工作..我檢查了.. :)感覺嫉妒你..爲什麼我沒有想到的那部分.. :))):D –