2017-08-13 22 views
0

でハッシュの異なる配列から要素を持つハッシュを作成し、我々はこの配列を与えられた。Bootcampの演習でルビー

library = [ 
    { 
    "title" => "Hitchhiker's Guide", 
    "Author" => "Douglas Adams", 
    "categories" => [ "comedy", "fiction", "british"] 
    }, 
    { 
    "title" => "Pride and Prejudice", 
    "Author" => "Jane Austen", 
    "categories" => [ "morality", "fiction", "society", "british"] 
    }, 
    { 
    "title" => "Search Inside Yourself", 
    "Author" => "Chade-Meng Tan", 
    "categories" => [ "self improvement", "non-fiction", "mindfulness", "business"] 
    }, 
    { 
    "title" => "Benjamin Franklin: An American Life", 
    "Author" => "Walter Isaacson", 
    "categories" => [ "non-fiction", "history", "founding fathers"] 
    }, 
    { 
    "title" => "Glengarry Glen Ross", 
    "Author" => "David Mamet", 
    "categories" => [ "play", "fiction", "drama"] 
    } 
] 

、我々は要素などのカテゴリで新しいハッシュを作成する必要があり、値としてのタイトル。

category_hashの作り方を理解することはできましたが、各カテゴリにタイトルを追加する方法はわかりません。ここに私のコードです:

category_hash = {} 
sub_category = [] 

library.each do |book| 
    book["categories"].each do |category| 
    sub_category << category 
    end 
    sub_category.each do |index| 
    category_hash[index] = "I'm not sure how to append the titles here" 
    end 
end 

p category_hash 

誰かが私にこのステップを理解させる助けになることができますか?

+0

あなたが意味することを「編集して」、「...要素としてのカテゴリ...」を明確にする必要があります。まず、 "要素"ではなく "キー"を意味します。すべての回答が同じように解釈されるわけではありません。今日まで、一つの答えは、 "categories"は、 'library'の要素(ハッシュ)のキー' 'categories" 'に関連する値であると仮定します。 2つの答えは、「カテゴリ」は、「ライブラリ」の要素(「コメディ」、「フィクション」、「英国」、「道徳」、「社会」など)の要素の「カテゴリ」の1つ以上の値に含まれる文字列であると仮定します。 。私は後者の解釈を意図していると思います。 –

答えて

2

あなたはEnumerable#each_with_object使用することができます:ここで

library.each_with_object({}) do |hash, result| 
    result[hash['categories']] = hash['title'] 
end 
# { 
# ["comedy", "fiction", "british"]=>"Hitchhiker's Guide", 
# ["morality", "fiction", "society", "british"]=>"Pride and Prejudice", 
# ["self improvement", "non-fiction", "mindfulness", "business"]=>"Search Inside Yourself", 
# ["non-fiction", "history", "founding fathers"]=>"Benjamin Franklin: An American Life", 
# ["play", "fiction", "drama"]=>"Glengarry Glen Ross" 
# } 
+0

別のハッシュがキー値ペア '" categories "=> [" comedy "、" fiction "、" british "]'を含む 'librar'に追加されたとします。それでは?質問に対する私のコメントを参照してください。 –

1

をAndreyDeinekoの答え@よりも効率である、それを行うための別の方法です。

library.map{|h| h.values_at("categories", "title")}.to_h 

結果:あなたは、当然のことながら、配列のハッシュ項目の順序に依存することになる、("category"属性によって配布されると思った場合には

{ 
    ["comedy", "fiction", "british"]=>"Hitchhiker's Guide", 
    ["morality", "fiction", "society", "british"]=>"Pride and Prejudice", 
    ["self improvement", "non-fiction", "mindfulness", "business"]=>"Search Inside Yourself", 
    ["non-fiction", "history", "founding fathers"]=>"Benjamin Franklin: An American Life", 
    ["play", "fiction", "drama"]=>"Glengarry Glen Ross" 
} 

;私は仮定あなたが意味後で1)は、以前の1よりも優先されます:

library.each_with_object({}) do 
    |h, result| h["categories"].each_with_object(result) do 
    |k, result| result[k] = h["title"] 
    end 
end 

結果:

{ 
    "comedy"=>"Hitchhiker's Guide", 
    "fiction"=>"Glengarry Glen Ross", 
    "british"=>"Pride and Prejudice", 
    "morality"=>"Pride and Prejudice", 
    "society"=>"Pride and Prejudice", 
    "self improvement"=>"Search Inside Yourself", 
    "non-fiction"=>"Benjamin Franklin: An American Life", 
    "mindfulness"=>"Search Inside Yourself", 
    "business"=>"Search Inside Yourself", 
    "history"=>"Benjamin Franklin: An American Life", 
    "founding fathers"=>"Benjamin Franklin: An American Life", 
    "play"=>"Glengarry Glen Ross", 
    "drama"=>"Glengarry Glen Ross" 
} 
1

initialize the Hashの場合は、カテゴリ内の各書籍のリストと複数のカテゴリのブックを表示するには、default_procを添付して、未知のすべてのキーに値として配列を含めることができます。そして、あなたは単にライブラリ内の各書籍を反復し、それがでていますすべてのカテゴリのリストにそれがタイトルです追加:

# Pass the category hash a default proc, which will be called 
# whenever a key it doesn't have is accessed. So, when you 
# encounter a brand new category, it'll already be set up with 
# an array 
category_hash = Hash.new { |hash, key| hash[key] = [] } 
library.each do |book| 
    book['categories'].each do |category| 
    # since we passed the default, no worrying, an array will be 
    # there and we can just add our value into it 
    category_hash[category] << book['title'] 
    end 
end 

puts category_hash 

結果:あなたは

にこれを修正することができるように

{ 
    "comedy"=>["Hitchhiker's Guide"], 
    "fiction"=>["Hitchhiker's Guide", "Pride and Prejudice", "Glengarry Glen Ross"], 
    "british"=>["Hitchhiker's Guide", "Pride and Prejudice"], 
    "morality"=>["Pride and Prejudice"], 
    "society"=>["Pride and Prejudice"], 
    "self improvement"=>["Search Inside Yourself"], 
    "non-fiction"=>["Search Inside Yourself", "Benjamin Franklin: An American Life"], 
    "mindfulness"=>["Search Inside Yourself"], 
    "business"=>["Search Inside Yourself"], 
    "history"=>["Benjamin Franklin: An American Life"], 
    "founding fathers"=>["Benjamin Franklin: An American Life"], 
    "play"=>["Glengarry Glen Ross"], 
    "drama"=>["Glengarry Glen Ross"] 
} 

each_with_objectもあります

result = library.each.with_object(Hash.new { |hash, key| hash[key] = [] }) do |book, category_hash| 
    book['categories'].each do |category| 
    # since we passed the default, no worrying, an array will be 
    # there and we can just add our value into it 
    category_hash[category] << book['title'] 
    end 
end 
puts result 

category_hashを返し、最後のコード行を保存します。

puts(library.each.with_object(Hash.new { |hash, key| hash[key] = [] }) do |book, category_hash| 
    book['categories'].each do |category| 
    # since we passed the default, no worrying, an array will be 
    # there and we can just add our value into it 
    category_hash[category] << book['title'] 
    end 
end) 
1

これは、他の回答のわずかな変形です。