2016-08-01 60 views
0

我有一個整數一個這樣的數組:集團整數的範圍的哈希值的陣列和計數

[1, 1, 1, 2, 2, 4, 4, 5, 6, 11, 11, 12, 15, 22, 23, 23, 23, 31, 32, 32] 

我試圖將其轉換爲一個哈希,分組根據在10個間隔的範圍。 ...

因此,在這種情況下,它會

{ [1..10] => 9, [11..20] => 4, [21..30] => 4, [31..40] => 3 } 

我曾嘗試還沒有接近所以這是一個有點無意義把它們倒在這裏的幾件事情。我可以將數組轉換爲範圍

[1, 1, 1, 2, 2, 4, 4, 5, 6, 11, 11, 12, 15, 22, 23, 23, 23, 31, 32, 32].sort.uniq.inject([]) do |spans, n| 
    if spans.empty? || spans.last.last != n - 1 
     spans + [n..n] 
    else 
     spans[0..-2] + [spans.last.first..n] 
    end 
    end 

但是這不是我正在尋找的。有什麼建議麼?

回答

2
Hash[ 
    your_array.group_by{|i| i/10}.map{|k,v| 
    [(k*10+1..(k+1)*10), v.count] 
    } 
] 
#=> {1..10=>9, 11..20=>4, 21..30=>4, 31..40=>3} 
+0

太棒了!非常感謝 – GhostRider

+0

看起來更像O(3n)給我。但是當然,你的解決方案速度更快。 –

+0

對於'your_array = [5,25]',你的解決方案返回'=> {1..10 => 1,21..30 => 1}',而不是'{1..10 => 1,11 ..20 => 0,21..30 => 1}'。如果你的散列是'h',那麼添加'h.default = 0'可能會令人滿意。 –

3
arr.each_with_object(Hash.new(0)) do |e, hash| 
    i = e/10 
    hash[i*10+1..i*10+10] += 1 
end 
#⇒ { 
# 1..10 => 9, 
# 11..20 => 4, 
# 21..30 => 4, 
# 31..40 => 3 
# } 
+0

我對@ Mladan的回答的評論也適用於你。 –

+0

@CarySwoveland的確如此,但當我明確要求時,我會返回'​​0':'result [11..20]#⇒0':) – mudasobwa

+0

哎呀!我錯過了哈希定義。我剛剛改變了我的評論以表明,但像往常一樣,你是領先一步。 –

2

我修改的例子爲具有21和30之間沒有號碼,使得散列應包括鍵 - 值對21..30=>0

arr = [1, 1, 1, 2, 2, 4, 4, 5, 6, 11, 11, 12, 20, 32, 33, 33, 33, 41, 42, 42] 

intervals = (1..arr.last-1).step(10).each_with_object({}) { |n,h| h[n..n+9] = 0 } 
    #=> {1..10=>0, 11..20=>0, 21..30=>0, 31..40=>0, 41..50=>0} 

arr.each_with_object(intervals) do |n,intervals| 
    interval_end = 10*((n+9)/10)  
    intervals[interval_end-9..interval_end] += 1 
end 
    #=> {1..10=>9, 11..20=>4, 21..30=>0, 31..40=>4, 41..50=>3}