2016-07-13 11 views
0
@members = { 
      approved: ["Jill"], 
      unapproved: ["Daniel"], 
      removed: ["John"], 
      banned: ["Daniel", "Jane"] 
     } 

非常に単純に:メンバーシップを追跡するプログラムを作成する。上記のハッシュでは、4つのメンバシップステータスキーがそれぞれ名前を含む配列で表示されます。ハッシュ内の配列内の要素を見つける

私は、ユーザーが名前を入力することができ、その後、名前のために各配列を検索し、キー名がで発見されたユーザーに伝えるfind_memberメソッドを作成しようとしている。

私はとてもじゃない

私はループの混乱を作成して、私は非常に簡単な解決策があると想像している、私は今までそれを見つけていない。これを行うには本当に簡単な方法がありますか?

私はいくつかのことを試しても、すべて私の過去の努力を持っていないが、これは私が以前持っていたものよりもおそらく悪いです私が終わってきた最新の混乱、次のとおりです。

def find_member 
    puts "==Find Member==" 
    puts "Name: " 
    @name = gets.chomp 
    @members.each do |key| 
    key.values.each do |array| 
     array.each do |element| 
     if @name == element 
      puts "#{@name} found in #{key}" 
     else 
      puts "#{@name} not found in #{key}" 
     end 
     end 
    end 
    end 
end 

ありがとうございます。

+0

あなたの努力を示してください。 –

+0

@d_zero私の答えはあなたのオリジナルの '@ members'ハッシュのために間違いなくあなたが作った変更をしなければならないと言うように、うまくいきます。私はこの段階で本当にあなたを助けることができません。私はOPを変更することをお勧めできません。なぜなら、現在の回答では不公平になるからです。あなたの問題を解決できない場合は、私の唯一の提案は別の質問を投稿することです。がんばろう。 –

+0

@ sagarpandya82うん、私は間違いを認識してから働いていないことに関する私のコメントを削除しました。どういうわけか、私は実際に '@ members'を定義していなかったので、今すぐソートしました。ご協力ありがとうございました。 –

答えて

0

これを行う最も効率的な方法は、名前のキーへの一対多マッピングを作成し、@membersが変更されたときにのみそのマッピングを更新することです。 @old_members_hashcodenilに初めてupdate_names_to_keys_if_necessaryを評価することを

def find_member(name) 
    update_names_to_keys_if_necessary 
    @member_to_keys[name] 
end 

def update_names_to_keys_if_necessary 
    new_hashcode = @members.hash 
    return if @old_members.hashcode == new_hashcode 
    @member_to_keys = @members.each_with_object(Hash.new { |h,k| h[k] = [] }) { |(k,v),h| 
    v.each { |name| h[name] << k } } 
    @old_members_hashcode = new_hashcode 
end 

注意が呼び出されるので、@member_to_keysは、その時点で作成されます。

当初、我々は

@member_to_keys 
    #=> {"Jill"=>[:approved], "Daniel"=>[:unapproved, :banned], 
    # "John"=>[:removed], "Jane"=>[:banned]} 

を得るには、それを試してみてください。

find_member("Jill") 
    #=> [:approved] 
find_member("Daniel") 
    #=> [:unapproved, :banned] 
find_member("John") 
    #=> [:removed] 
find_member("Jane") 
    #=> [:banned] 
find_member("Billy-Bob") 
    #=> [] 
0

include?メソッドでこの繰り返しを使用できます。

@members = { 
    approved: ["Jill"], 
    unapproved: ["Daniel"], 
    removed: ["John"], 
    banned: ["Daniel", "Jane"] 
} 

def find_member_group(name) 
    @members.each { |group, names| return group if names.include?(name) } 
    nil 
end 

@name = 'Jane' 

group_name = find_member_group(@name) 
puts group_name ? "#{@name} found in #{group_name}." : "#{@name} not found." 
# => Jane found in banned. 
0

Hash#selectここで使用するための方法である:

def find_member(name) 
    @members.select {|k,v| v.include? name }.keys 
end 

find_member("Jill") #=> [:approved] 
find_member("Daniel") #=> [:unapproved, :banned] 
find_member("John") #=> [:removed] 
find_member("Jane") #=> [:banned] 

説明:

select名前がで条件を満たして要素のみをマップを選択し、示唆するように対応するコードブロック。コードブロックは、ifステートメントの必要性を否定します。コードブロック内の我々は、各キーと値のペアをチェックし、その値場合name引数、そのキーと値のペアを選択して最終的な出力にマッピングされるを含みます。最後に、メンバーシップ(つまりキー)のみに興味があるので、keysメソッドを適用して配列の形で取得します。

関連する問題