2015-12-30 61 views
-2

是否有任何內置方法可用於將大陣列拆分爲具有動態下降因子的較小塊?紅寶石陣列與下降因子的子陣列

例如:i=0 src_arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

如果batch_size = 5fall_factor = 1,第一組塊應該是[1, 2, 3, 4, 5]和隨後的陣列塊應該從start_index = i * (batch_size - fall_factor)啓動。即,start_index0, 4, 8, 12

result: [1, 2, 3, 4, 5] 
[5, 6, 7, 8, 9] 
[9, 10, 11, 12, 13] 
[13, 14] 

如果fall_factor = 2結果應該是如下

[1, 2, 3, 4, 5] 
[4, 5, 6, 7, 8] 
[7, 8, 9, 10, 11] 
[10, 11, 12, 13, 14] 

我知道如何解決這個問題。我的問題是,如果有任何內置的方法可用,如each_slice來完成這項工作,而不是重新發明。

+4

你能舉出更多的例子/解釋批量大小和下降因子如何預計工作? – ndn

+0

@ndn:我希望你現在可以得到它 – Maheshkumar

+0

@Downvoter,你能解釋一下嗎? – Maheshkumar

回答

4

例如,你可以使用的Numeric

0.step(src_arr.size - fall_factor - 1, batch_size - fall_factor).map do |ind| 
    src_arr[ind, batch_size] 
end 

# fall_factor = 1 
# => [[1, 2, 3, 4, 5], [5, 6, 7, 8, 9], [9, 10, 11, 12, 13], [13, 14]] 
# fall_factor = 2 
# => [[1, 2, 3, 4, 5], [4, 5, 6, 7, 8], [7, 8, 9, 10, 11], [10, 11, 12, 13, 14]] 
+2

這是唯一正確的解決方案。但也許,'[開始,長度]'結構比'[範圍]'更好。 – sawa

0

根據由您共享邏輯只是#step方法,下面是一個可能的實現:

b = 5 # batch size 
f = 2 # fall factor 

indices = (0...src_arr.size).collect {|i| i * (b-f)}.reject {|i| i + f >= src_arr.size} 

result = indices.each_with_object([]) do |i, obj| 
    obj << src_arr[i, b] 
end 
p result 
#=> [[1, 2, 3, 4, 5], [4, 5, 6, 7, 8], [7, 8, 9, 10, 11], [10, 11, 12, 13, 14]] 
+0

這不是OP想要的。 – sawa

+1

@sawa感謝您扮演[裁判]的角色(http://i.dailymail.co.uk/i/pix/2014/07/12/article-0-02B0114C0000044D-243_634x428.jpg):-) –

1

代碼

def doit(arr, batch_size, fall_factor) 
    arr[batch_size..-1]. 
    each_slice(batch_size-fall_factor). 
    each_with_object([arr[0,batch_size]]) { |b,c| c << [*c.last[-fall_factor..-1], *b] } 
end 

個例子

arr = (1..14).to_a 
    #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] 

doit(arr, 5, 1) 
    #=> [[1, 2, 3, 4, 5], [5, 6, 7, 8, 9], [9, 10, 11, 12, 13], [13, 14]] 
doit(arr, 5, 2) 
    #=> [[1, 2, 3, 4, 5], [4, 5, 6, 7, 8], [7, 8, 9, 10, 11], [10, 11, 12, 13, 14]] 
doit(arr, 5, 3) 
    #=> [[1, 2, 3, 4, 5], [3, 4, 5, 6, 7], [5, 6, 7, 8, 9], [7, 8, 9, 10, 11], 
    # [9, 10, 11, 12, 13], [11, 12, 13, 14]] 
doit(arr, 5, 4) 
    #=> [[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7], [4, 5, 6, 7, 8], 
    # [5, 6, 7, 8, 9], [6, 7, 8, 9, 10], [7, 8, 9, 10, 11], [8, 9, 10, 11, 12], 
    # [9, 10, 11, 12, 13], [10, 11, 12, 13, 14]] 

說明

對於上述arr和:

batch_size = 5 
fall_factor = 2 

我們:

a = arr[batch_size..-1] 
    #=> arr[5..-1] 
    #=> [6, 7, 8, 9, 10, 11, 12, 13, 14] 
b = a.each_slice(batch_size-fall_factor) 
    #=> a.each_slice(3) 
    #=> #<Enumerator: [6, 7, 8, 9, 10, 11, 12, 13, 14]:each_slice(3)> 

我們可以看到枚舉的元素通過將其轉換爲一個數組:

b.to_a 
    #=> [[6, 7, 8], [9, 10, 11], [12, 13, 14]] 

繼續:

d = [arr[0,batch_size]] 
    #=> [[1, 2, 3, 4, 5]] 
b.each_with_object(d) { |b,c| c << [*c.last[-fall_factor..-1], *b] } 
    #=> [[1, 2, 3, 4, 5], [4, 5, 6, 7, 8], [7, 8, 9, 10, 11], [10, 11, 12, 13, 14]] 

要了解如何執行最後的計算,讓:

e = b.each_with_object(d) 
    #=> #<Enumerator: #<Enumerator: [6, 7, 8, 9, 10, 11, 12, 13, 14]: 
    #  each_slice(3)>:each_with_object([[1, 2, 3, 4, 5]])> 
e.to_a 
    #=> [[[6, 7, 8], [[1, 2, 3, 4, 5]]], 
    # [[9, 10, 11], [[1, 2, 3, 4, 5]]], 
    # [[12, 13, 14], [[1, 2, 3, 4, 5]]]] 

我們可以使用Enumerator#next以獲得每個元素傳遞給塊的e,將塊變量設置爲每個值並執行塊計算。第一元件被傳遞到塊:

b, c = e.next 
    #=> [[6, 7, 8], [[1, 2, 3, 4, 5]]] 
b #=> [6, 7, 8] 
C#=> [[1, 2, 3, 4, 5]] 

塊計算因此是:

c << [*c.last[-fall_factor..-1], *b] 
    #=> c << [*[[1, 2, 3, 4, 5]].last[-2..-1], *[6, 7, 8]] 
    # c << [*[1, 2, 3, 4, 5][-2..-1], *[6, 7, 8]] 
    # c << [*[4, 5], *[6, 7, 8]] 
    # c << [4, 5, 6, 7, 8] 
C#=> [[1, 2, 3, 4, 5], [4, 5, 6, 7, 8]] 

e下一個元素現在傳遞到塊:

b, c = e.next 
    #=> [[9, 10, 11], [[1, 2, 3, 4, 5], [4, 5, 6, 7, 8]]] 
b #=> [9, 10, 11] 
C#=> [[1, 2, 3, 4, 5], [4, 5, 6, 7, 8]] 

剩餘計算是類似地執行的。

+0

非常做得很好 –