2011-04-16 105 views
17

根據某些條件將數組拆分爲多個數組的最簡單方法是什麼?在我的場景中,我需要將整數和字符串值移動到不同的數組。我試過split方法,但不能按預期工作。在ruby中將數組拆分爲多個小數組的最佳方法

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

在C#中,存在一個Linq選擇group by,它可以幫助您組基於條件的對象。 Object(不使用activerecord)有沒有類似的方法?

有沒有簡單的方法?

回答

38

您正在尋找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"]] 
+0

+ 1爲單線和雙重任務。看起來不錯。 – slhck 2011-04-16 12:45:47

+0

+1這對於速度來說也是一個可靠的勝利!查看我添加的基準。 – 2011-04-17 04:16:47

+3

下面的答案使用'group_by',它允許分成兩個以上的組。 – 2013-10-26 04:02:05

3

這裏是我的解決方案:

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 
5

嘗試:

x.group_by {|x| x.class} 

您可以通過然後調用to_a得到一個數組回來在你給出的例子中的結果將返回:

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

只是一些更多的解決方案扔到池:

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) 
+0

奇怪的是,我發現'.partition'更快,甚至創建2個數組,並且執行'.each'和'if e.kind_of(Fixnum)'。我猜他們正在爲C中的'.partition'做一些優化。 – Dogbert 2011-04-17 09:35:35

+0

我沒有看過源代碼,但我有同樣的懷疑。 – 2011-04-17 09:47:56

相關問題