2014-10-07 55 views
4

我希望得到一個嵌套數組,其中包含具有最少三個元素但最多四個元素的單個數組。我遇到了一個問題,當我到達10:Ruby上的Each_Slice陣列

example = [1,2,3,4,5,6,7,8,9,10] 

example.each_slice(3).to_a = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]] 
example.each_slice(4).to_a = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]] 

期望的結果是:

[[1, 2, 3], [4, 5, 6], [7, 8, 9, 10]]  (all arrays have 3 elements but no more than 4) 

是each_slice不要去這樣做的方法是什麼?

謝謝

+2

這裏有三種可能性拆分此陣在這種情況下這種方式。其中之一是[[1,2,3,4],[5,6,7],[8,9,10]]你能否澄清是否3-3-4?什麼在12元素陣列的情況下,它應該全部是三分還是四分? – BroiSatse 2014-10-08 00:08:23

+1

請問['in_groups_of'](http://apidock.com/rails/Array/in_groups_of)有幫助嗎?它通過用'nil'填充來保證一致的組大小。 – 2014-10-08 01:21:24

+0

謝謝Mark!即使存在,我也不知道in_groups_of。它看起來像這將工作! BroiSatse - 對不起,我應該說,它可以是任何變化,只要至少有三個元素,不超過四個。在12的情況下,可能是4-4-4或3-3-3-3,任何一個都可以工作。 – user3007294 2014-10-08 01:39:06

回答

2

each_slice產生切片達到所需的大小;它不會直接完成你想要的東西,這是對列表的「平衡」。幸運的是,我們可以到達那裏。

list = (1..10).to_a 
slice_count = (list.length/3.0).floor 
list.each_slice(slice_count).to_a.each {|l| l.fill nil, slice_count, 0 }.transpose.map(&:compact) 
# => [[1, 4, 7, 10], [2, 5, 8], [3, 6, 9]] 

這並不保留排序,但它確實平衡了這些值。這種方式的工作原理是,它基本上創建了一個矩陣,其中至少每列的前3行被填充,第四列用於捕獲溢出。

1 2 3 
4 5 6 
7 8 9 
10 - - 

然後使用#transpose從列創建數組,然後我們緊湊以刪除nils。

保留訂單有點困難,並且需要一些條件。具有3/4個元素的陣列的期望分佈將在這種情況下影響答案。

+0

完美!我很欣賞這個克里斯!很好的解釋。效果很好 – user3007294 2014-10-08 01:36:43

1

這是您可以做到的一種方式,它可以保留順序並使包含三個元素的數組數量最大化,並在末尾放置零個,一個或兩個四個數組。

代碼

def divide_up(arr) 
    sz = arr.size 
    return nil if [0,1,2,5].include?(sz) 
    n3, d = sz.divmod(3) 
    return arr.each_slice(3).to_a if d.zero? 
    return arr.each_slice(4).to_a if d==n3 
    n3 -= d 
    arr[0,3*n3].each_slice(3).to_a + arr[3*n3..-1].each_slice(4).to_a 
end 

d==n3在方法的第五行是(d==1 && n3==1) || (d==2 && n3==2)簡寫。

例子

16.times do |n| 
    arr = [*1..n] 
    puts "for: #{arr}:" 
    a=divide_up(arr) 
    puts " #{(a ? a : "No solution")}" 
end 
    #=> for: []: 
    #  No solution 
    # for: [1]: 
    #  No solution 
    # for: [1, 2]: 
    #  No solution 
    # for: [1, 2, 3]: 
    #  [[1, 2, 3]] 
    # for: [1, 2, 3, 4]: 
    #  [[1, 2, 3, 4]] 
    # for: [1, 2, 3, 4, 5]: 
    #  No solution 
    # for: [1, 2, 3, 4, 5, 6]: 
    #  [[1, 2, 3], [4, 5, 6]] 
    # for: [1, 2, 3, 4, 5, 6, 7]: 
    #  [[1, 2, 3], [4, 5, 6, 7]] 
    # for: [1, 2, 3, 4, 5, 6, 7, 8]: 
    #  [[1, 2, 3, 4], [5, 6, 7, 8]] 
    # for: [1, 2, 3, 4, 5, 6, 7, 8, 9]: 
    #  [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 
    # for: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]: 
    #  [[1, 2, 3], [4, 5, 6], [7, 8, 9, 10]] 
    # for: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]: 
    #  [[1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]] 
    # for: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]: 
    #  [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]] 
    # for: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]: 
    #  [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12, 13]] 
    # for: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]: 
    #  [[1, 2, 3], [4, 5, 6], [7, 8, 9, 10], [11, 12, 13, 14]] 
    # for: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]: 
    #  [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15]]