2016-07-13 17 views
0

入力としてハッシュを取るRuby関数が必要です(キーはシンボルと数値は配列の数値です)。関連する配列の最初の値が同じであるキーのリストを返します。ここハッシュのための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つの配列における同一の値として2表示されるので:K1:K3。 returnオブジェクトは配列の配列です(キーのいくつかのグループは同じ配列の最初の値を持つことができるため)。

これまでのところ、私は配列そのものをグループ化:

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

示唆:

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

あなたは、これはさらに処理するために使用することができます。これは、あなたにこのような何かを与える

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

。ちょうどキーが欲しいですか?

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] 

希望に役立ちます!なぜだけではなく、あなたの質問のタイトルとしてgroup_byを使用

関連する問題