Best way to split arrays into multiple small arrays in ruby
You're looking for Enumerable#partition:
x = [1, 2, 3, "a", "b", 4]numbers, not_numbers = x.partition{|item| item.kind_of?(Fixnum)}# => [[1, 2, 3, 4], ["a", "b"]]
Just to throw some more solutions into the pool:
x = [1,2,3,"a","b",4]numbers = x.select{ |e| e.is_a?(Fixnum) } # => [1, 2, 3, 4]letters = x - numbers # => ["a", "b"]numbers = x.select{ |e| e.kind_of?(Fixnum) } # => [1, 2, 3, 4]letters = x - numbers # => ["a", "b"]
or
(numbers, letters) = x.group_by {|a| a.class}.values_at(Fixnum, String)numbers # => [1, 2, 3, 4]letters # => ["a", "b"]
Along with some benchmarks showing how a subtle change effects speed:
require 'benchmark'x = [1,2,3,"a","b",4] * 100n = 10_000Benchmark.bm do |bench| bench.report { n.times { numbers = x.select{ |e| e.is_a?(Fixnum) } letters = x - numbers }} bench.report { n.times { numbers = x.select{ |e| e.kind_of?(Fixnum) } letters = x - numbers }} bench.report { n.times { (numbers, letters) = x.group_by {|a| a.class}.values_at(Fixnum, String) }} bench.report { n.times { numbers, not_numbers = x.partition{|item| item.kind_of? Fixnum} }}end# >> user system total real# >> 4.270000 0.010000 4.280000 ( 4.282922)# >> 4.290000 0.000000 4.290000 ( 4.288720)# >> 5.160000 0.010000 5.170000 ( 5.163695)# >> 3.720000 0.000000 3.720000 ( 3.721459)