2012-09-11 107 views
48

我需要一種方法將數組拆分爲另一個大小相等的數組中的數組。任何人有任何這樣做的方法?在紅寶石中將數組拆分成相等部分

例如

a = [0, 1, 2, 3, 4, 5, 6, 7] 
a.method_i_need(3) 
a.inspect 
    => [[0,1,2], [3,4,5], [6,7]] 
+3

可能重複[如何將一個Ruby數組拆分(塊)成X部分?](http://stackoverflow.com/questions/2699584/how-to-split-chunk-a-ruby -array-into-parts-of-x-elements) –

+8

不幸的是,所選擇的例子對於「3分組分組」和「3分組分組」有相同的結果,這就是爲什麼你有兩個完全不同的答案。 – tokland

回答

102

您正在尋找Enumerable#each_slice

a = [0, 1, 2, 3, 4, 5, 6, 7] 
a.each_slice(3) # => #<Enumerator: [0, 1, 2, 3, 4, 5, 6, 7]:each_slice(3)> 
a.each_slice(3).to_a # => [[0, 1, 2], [3, 4, 5], [6, 7]] 
+6

這些基本問題和答案如何吸引最多的熱門話題,這很有趣。 –

+12

只是一個筆記。這將數組分成3個大小的組,而不是3個相等大小的組。 – yasith

+0

如果數組大小沒有均勻地劃分成片數,是否可以合併剩餘片和前一片?以你的例子來說,'[6,7]'將與'[3,4,5]'合併成[[3,4,5,6,7]]。 – Mohamad

13

嘗試

a.in_groups_of(3,false) 

它會做你的工作

+12

請注意['in_groups_of'](http://rails.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Array/Grouping.html)特定於Rails(或更確切地說,ActiveSupport),而@ Joshua的答案在Ruby中可用到處。然而,+1提供了一個工作解決方案。 – Phrogz

+0

它也只在[Array]上(https://github.com/rails/rails/blob/ccf9577aee86ce1f766c5e8854e0c285dc38f8ac/activesupport/lib/active_support/core_ext/array/grouping.rb)。 –

+0

@Phrogz感謝信息 –

89

也許我誤讀的問題1因爲另一個答案已經被接受了,但是聽起來好像你想把數組分成3個相等的組,而不管每個組的大小如何,而不是像以前的答案那樣將它分成3組。如果這是你在找什麼,鐵軌(的ActiveSupport)也有一個叫in_groups方法:

a = [0,1,2,3,4,5,6] 
a.in_groups(2) # => [[0,1,2,3],[4,5,6,nil]] 
a.in_groups(3, false) # => [[0,1,2],[3,4], [5,6]] 

我不認爲這是一個相當於紅寶石然而,您可以通過添加此得到大致相同的結果簡單的方法:

class Array; def in_groups(num_groups) 
    return [] if num_groups == 0 
    slice_size = (self.size/Float(num_groups)).ceil 
    groups = self.each_slice(slice_size).to_a 
end; end 

a.in_groups(3) # => [[0,1,2], [3,4,5], [6]] 

唯一的區別(你可以看到)是,這不會傳播所有組的「空白空間」;除了最後一個組以外,每個組的大小相等,最後一組總是包含剩餘的加上所有的「空白空間」。

更新: 作爲@rimsky敏銳地指出,上述方法不會總是產生正確的組數(有時它會創建在年底多個「空組」,並留下出來)。這裏有一個更新版本,從ActiveSupport's definition削減,其中擴展出來,以填補所需的組數。

def in_groups(number) 
    group_size = size/number 
    leftovers = size % number 

    groups = [] 
    start = 0 
    number.times do |index| 
    length = group_size + (leftovers > 0 && leftovers > index ? 1 : 0) 
    groups << slice(start, length) 
    start += length 
    end 

    groups 
end 
+3

我知道這是一箇舊帖子,但對於那些正在考慮上面的紅寶石等價物,這是不正確的。如果您嘗試將20個元素的數組分成11個組,則最終只有10個組。 slice_size將是2,並且20可以被2整除。 – rimsky

+0

這是我來這裏尋找的。不適用於n大小的團體,如接受的答案。謝謝。 –

+0

很好的@rimsky!更新;) – mltsy

0

正如mltsy寫道,in_groups(n, false)應該做的工作。

我只是想添加一個小竅門,以獲得合適的餘額 my_array.in_group(my_array.size.quo(max_size).ceil, false)

這裏是要說明,招一個例子:

a = (0..8).to_a 
a.in_groups(4, false) => [[0, 1, 2], [3, 4], [5, 6], [7, 8]] 
a.in_groups(a.size.quo(4).ceil, false) => [[0, 1, 2], [3, 4, 5], [6, 7, 8]] 
1

這需要一些更好的聰明塗抹掉多餘的碎片,但它是一個良好的開端。

def i_need(bits, r) 
    c = r.count 
    (1..bits - 1).map { |i| r.shift((c + i) * 1.0/bits) } + [r] 
end 

> i_need(2, [1, 3, 5, 7, 2, 4, 6, 8]) 
=> [[1, 3, 5, 7], [2, 4, 6, 8]] 
> i_need(3, [1, 3, 5, 7, 2, 4, 6, 8]) 
=> [[1, 3, 5], [7, 2, 4], [6, 8]] 
> i_need(5, [1, 3, 5, 7, 2, 4, 6, 8]) 
=> [[1, 3], [5, 7], [2, 4], [6], [8]]