2016-07-13 38 views
0

我需要一個以散列作爲輸入(鍵是符號和值是數組陣列)的Ruby函數,並返回其關聯數組具有相同第一個值的鍵的列表。紅寶石'group_by'類似的散列方法

下面是一個例子:

h={ 
    :k1 => [2,3,5,12], 
    :k2 => [9,5,6,10], 
    :k3 => [2,4,5, 8], 
} 

f(h) # should return [[:k1,:k3]] 

...因爲2只出現在與相關聯的兩個陣列相同的值:K1:K3。返回Object是一個數組數組(因爲,幾組鍵可以具有相同的數組第一個值)。

到目前爲止,我只是分組的陣列本身:

def f(h) 
    h.values.group_by{|ary| ary.first} 
end 

# returns {2=>[[2, 3, 5, 12], [2, 4, 5, 8]], 9=>[[9, 5, 6, 10]]} 

回答

2

爲什麼不直接使用group_by你的問題的標題所說:

h2 = h.group_by { |k, v| v.first } 

這給了你這樣的事情:

{2=>[[:k1, [2, 3, 5, 12]], [:k3, [2, 4, 5, 8]]], 9=>[[:k2, [9, 5, 6, 10]]]} 

然後,您可以使用此作進一步處理。只需要鑰匙?

h3 = h2.values.map { |v| v.map(&:first) } 

只希望擁有多個關鍵字的人?

h3.reject { |v| v.length < 2 } 

或者對h2直接:

h2.reject { |k, v| v.length < 2 } 
+0

我根本不知道這種方法的散列。謝謝 ! – JCLL

0

也許你可以使用這樣的事情

def get_same_first_value(h) 
    h.each_with_object(Hash.new { |k, v| k[v] = [] }) do |(sym, arr), exp| 
    exp[arr.min] << sym 
    end.select { |k, v| v.size != 1 }.values 
end 

h = { 
    :k1 => [2, 3, 5, 12], 
    :k2 => [9, 5, 6, 10], 
    :k3 => [2, 4, 5, 8], 
} 

get_same_first_value(h) 
# => [[:k1, :k3]] 
1

我想出了這個醜陋的東西:

h.inject({}) do |memo, (key, array)| 
    memo[array[0]] ||= [] 
    memo[array[0]] << key 
    memo 
end.detect do |(key, values)| 
    values.size > 1 
end.last 

它基本上以下列形式重新映射哈希:

{first_item_in_array => keys_that_contain_it} 

或者,在我們的例子:

{2=>[:k1, :k3]} 

那麼它只是檢測到有多於一個的匹配,並返回其第一對:

[:k1, :k3] 

希望幫助!