1

I've found this similar two questions to the one I'm about to ask:

Split array up into n-groups of m size? and Need to split arrays to sub arrays of specified size in Ruby

This splits array into three arrays with each array having three elements :

a.each_slice(3) do |x,y,z|
  p [x,y,z]
end

So if I do this (my array size is 1000) :

a.each_slice(200) do |a,b,c,d,e|
            p "#{a} #{b} #{c} #{d} #{e}"
        end

This should split my array into 5 arrays each having 200 members? But it doesn't? What I actually need to do is to put 200 random elements into 5 arrays, am I on the right track here, how can I do this?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Gandalf StormCrow
  • 25,788
  • 70
  • 174
  • 263
  • "This should split my array into 5 arrays each having 200 members? But it doesn't?" – How did you determine that? It does exactly what it's supposed to do: it splits your array into 5 arrays each having 200 members, then it prints the first 5 members of each of the 5 arrays, doesn't it? – Jörg W Mittag Feb 22 '13 at 12:03
  • Right, if you provide a single argument to the each_slice block it gives you an array, if you provide more than one argument then it will fill up those arguments until there are no arguments to fill or there are no values left to fill them with, in which case the extra arguments will be nil. – Cluster Feb 22 '13 at 12:07

4 Answers4

2

Enumerable#each_slice

If you provide a single argument to the block of each_slice then it will fill that argument with an array of values less than or equal to the given argument. On the last iteration if there are less than n values left then the array size will be whatever is left.

If you provide multiple arguments to the block of each_slice then it will fill those values with the values from the source array. If the slice size is greater than the number of arguments given then some values will be ignored. If it is less than the number of arguments than the excess arguments will be nil.

a = (1..9).to_a

a.each_slice(3) {|b| puts b.inspect }
[1,2,3]
[4,5,6]
[7,8,9]

a.each_slice(4) {|b| puts b.inspect }
[1,2,3,4]
[5,6,7,8]
[9]

a.each_slice(3) {|b,c,d| puts (b + c + d)}
6   # 1 + 2 + 3
15  # 4 + 5 + 6
24  # 7 + 8 + 9

a.each_slice(3) {|b,c| puts (b + c)}
3   # 1 + 2, skips 3
9   # 4 + 5, skips 6
15  # 7 + 8, skips 9

a.each_slice(2) {|b,c| puts c.inspect}
2
4
6
8
nil

a.each_slice(3) {|b,c,d,e| puts e.inspect}
nil
nil
nil
Cluster
  • 5,457
  • 1
  • 25
  • 36
1
irb(main):001:0> a= (1..10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
irb(main):002:0> a.sample(3)
=> [5, 10, 1]
irb(main):003:0> (1..3).map{ a.sample(3) }
=> [[6, 2, 5], [8, 7, 3], [4, 5, 7]]
irb(main):004:0> 
nurettin
  • 11,090
  • 5
  • 65
  • 85
0

If you want to assign that result to 5 different arrays, you could use the splat operator,like this:

a,b,c,d,e = *(1..1000).each_slice(200).to_a
fmendez
  • 7,250
  • 5
  • 36
  • 35
0

Actually you will return a string with the five elements inserted in it. You can try something:

a1 = [], a2 = [], a3 = [], a4 = [], a5 = []

a.each_slice(5) do |a,b,c,d,e|
  a1 << a
  a2 << b
  a3 << c
  a4 << d
  a5 << e
end

You will end up with five arrays containing 200 elements each. I used the simplest possible syntax to make it clear, you can make it much more condensed.