在Ruby中将数组拆分为多个小数组的最佳方法

根据某些条件将数组拆分成多个数组的最简单方法是什么? 在我的场景中,我需要将整数和字符串值移动到不同的数组。 我尝试过split方法,但是没有按预期工作。

 x=[1,2,3,"a","b",4] x.split {|item| item.kind_of? Fixnum} 

在C#中, Linq有一个group by选项,可帮助您根据条件对对象进行分组。 Object上是否有类似的方法(不使用activerecord)?

有一个简单的方法吗?

您正在寻找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"]] 

尝试:

 x.group_by {|x| x.class} 

你可以通过调用to_a来获取一个数组,结果在你给出的例子中将返回:

 [[Fixnum, [1, 2, 3, 4]], [String, ["a", "b"]]] 

只是为了向池中添加更多解决方案:

 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"] 

要么

 (numbers, letters) = x.group_by {|a| a.class}.values_at(Fixnum, String) numbers # => [1, 2, 3, 4] letters # => ["a", "b"] 

除了一些显示微妙变化影响速度的基准:

 require 'benchmark' x = [1,2,3,"a","b",4] * 100 n = 10_000 Benchmark.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) 

这是我的解决方案:

 hash = x.group_by { |t| t.kind_of? Fixnum } # hash => {true=>[1, 2, 3, 4], false=>["a", "b"]} array1 = hash[true] # The array of integers array2 = hash[false] # The array of strings