What is the simplest way to split arrays into multiple arrays based on some conditions? In my scenario, I need to move the integer and the string values to different arrays. I have tried split
method, but does not work as expected.
根据某些条件将数组拆分成多个数组的最简单方法是什么?在我的场景中,我需要将整数和字符串值移动到不同的数组。我尝试过拆分方法,但是没有按预期工作。
x=[1,2,3,"a","b",4]
x.split {|item| item.kind_of? Fixnum}
In C#, there is a group by
option in Linq
, which helps you group the objects based on the conditions. Is there a similar method on Object
(not using activerecord) ?
在C#中,Linq中有一个group by选项,可帮助您根据条件对对象进行分组。 Object上是否有类似的方法(不使用activerecord)?
Is there a simple way?
有一个简单的方法吗?
4 个解决方案
#1
38
You're looking for Enumerable#partition:
您正在寻找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"]]
#2
5
Try:
尝试:
x.group_by {|x| x.class}
You can get an array back by then calling to_a
on the result which in the example you've given will return:
你可以通过调用to_a来获取一个数组,结果在你给出的例子中将返回:
[[Fixnum, [1, 2, 3, 4]], [String, ["a", "b"]]]
#3
5
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] * 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)
#4
3
Here is my solution:
这是我的解决方案:
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
#1
38
You're looking for Enumerable#partition:
您正在寻找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"]]
#2
5
Try:
尝试:
x.group_by {|x| x.class}
You can get an array back by then calling to_a
on the result which in the example you've given will return:
你可以通过调用to_a来获取一个数组,结果在你给出的例子中将返回:
[[Fixnum, [1, 2, 3, 4]], [String, ["a", "b"]]]
#3
5
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] * 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)
#4
3
Here is my solution:
这是我的解决方案:
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