2012-12-28 112 views
3

假設我有以下的數組:紅寶石「bucketize」陣列

a = (1..10).to_a 

是否有一個單一內置紅寶石(或軌道)功能,其能夠或陣列分成確切的N大致相等的部分,而維持秩序?

我正在尋找這樣的事情:

a.bucketize(3) 
=> [[1,2,3,4],[5,6,7],[8,9,10]] 
a.bucketize(5) 
=> [[1,2],[3,4],[5,6],[7,8],[9,10]] 

提示:each_slice並沒有這樣做。

此外,我知道我可以自己寫這個函數,並打開Array類或Enumerable模塊。

謝謝。

+5

沒有,就沒有這樣的方法 – tokland

+0

沒有一個單一的方法,但有一個單一的線的方法來做到這個。 array.each_slice(3).map --- oops。不,我錯了。我錯過了你正在尋找的東西。 – digidigo

+0

似乎真的沒有辦法。所以關閉你的問題,如果不是在尋找一種方法 –

回答

4

我會做這樣的:

ary = (1..10).to_a 

ary.each_slice((ary.length.to_f/3).ceil).to_a 
=> [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]] 

ary.each_slice((ary.length.to_f/5).ceil).to_a 
=> [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]] 

它並不完美,但它確實接近:

ary = (1..9).to_a 
=> [1, 2, 3, 4, 5, 6, 7, 8, 9] 

ary.each_slice((ary.length.to_f/2).ceil).to_a 
=> [[1, 2, 3, 4, 5], [6, 7, 8, 9]] 

ary.each_slice((ary.length.to_f/3).ceil).to_a 
=> [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 

ary.each_slice((ary.length.to_f/4).ceil).to_a 
=> [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 
+0

我喜歡它,它絕對接近。不幸的是,我有一個嚴格的要求,那就是正好有N個桶。 – Finbarr

0

這裏是我落得這樣做:

class Array 
    def bucketize(n) 
    return [] if (buckets = n.to_i) <= 0 
    j = length/buckets.to_f 
    result = each_with_index.chunk { |_, i| (i/j).floor }.map { |_, v| v.map(&:first) } 
    result << [] until result.length == buckets 
    result 
    end 
end 

示例:

a = (1..10).to_a 
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
a.bucketize(1) 
=> [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]] 
a.bucketize(2) 
=> [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]] 
a.bucketize(3) 
=> [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]] 
a.bucketize(4) 
=> [[1, 2, 3], [4, 5], [6, 7, 8], [9, 10]] 
... 
a.bucketize(9) 
=> [[1, 2], [3], [4], [5], [6], [7], [8], [9], [10]] 
... 
a.bucketize(11) 
=> [[1], [2], [3], [4], [5], [6], [7], [8], [9], [10], []] 
2

使用功能性方法可以很好地解決這類任務。這裏的一個尾遞歸功能實現(除了不可避免的<<有效地積累在陣列):

class Array 
    def bucketize(n, index = 0, acc = []) 
    return acc if n <= 0 || size <= index 
    n0 = ((size - index).to_f/n).ceil 
    bucketize(n - 1, index + n0, acc << self[index, n0]) 
    end 
end 

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