Ruby 将对象推送到循环内的散列中

Ruby 将对象推送到循环内的散列中,ruby,hash,Ruby,Hash,我正在尝试实现以下JSON结果: { "movie" => [{ "title": "Thor", "year" : 2011, }, { "title": "Iron Man", "year" : 2008, }], "tv" =>

我正在尝试实现以下JSON结果:

 {
    "movie" =>
             [{
               "title": "Thor",
               "year" : 2011,
             },
             {
               "title": "Iron Man",
               "year" : 2008,
             }],
     "tv" =>  
             [{
               "title": "Parks and Recreation"
               "year": 2009
             },
             {
               "title": "Friends"
               "year": 1994
             }]
  }
使用JavaScript,我将循环查看结果并执行以下操作:

results['movie'].push(item);
results['tv'].push(item);
对于Ruby代码,我所做的最远的工作是:

@results = Hash.new
results['Search'].each do |r|
  if r['Type'] == 'movie'
    @results['movie'] << {
        'title' => r['Title'],
        'year' => r['Year']
    }
  elsif r['Type'] == 'series'
    @results['tv'] << {
        'title' => r['Title'],
        'year' => r['Year']
    }
  end
end         
@results=Hash.new
结果['Search']。每个都做| r|
如果r['Type']=='movie'
@结果['movie']r['Title'],
“年”=>r[“年”]
}
elsif r['Type']=='series'
@结果['tv']r['Title'],
“年”=>r[“年”]
}
终止
终止

我在这里遗漏了什么?

我认为问题与哈希的初始化有关。
movie
tv
键当前不是数组。您可以按如下方式初始化哈希:

@results = { 'movie' => [], 'tv' => [] }
下面是它与其余代码的外观:

@results = { 'movie' => [], 'tv' => [] }
results['Search'].each do |r|
  if r['Type'] == 'movie'
    @results['movie'] << {
        'title' => r['Title'],
        'year' => r['Year']
    }
  elsif r['Type'] == 'series'
    @results['tv'] << {
        'title' => r['Title'],
        'year' => r['Year']
    }
  end
end 
@results={'movie'=>[],'tv'=>[]
结果['Search']。每个都做| r|
如果r['Type']=='movie'
@结果['movie']r['Title'],
“年”=>r[“年”]
}
elsif r['Type']=='series'
@结果['tv']r['Title'],
“年”=>r[“年”]
}
终止
终止

我认为您可以通过使用
Enumerable#each#u with_object
并为散列指定一个默认值来获得所需内容

def group_search_results(items)
  results = Hash.new { |hash, key| hash[key] = [] }
  items.each_with_object(results) do |item|
    results[item['Type']] << {'title' => item['Title'], 'year' => item['Year']}
  end
end

describe "search_results" do
  it "groups into an object" do
    items = [
      {'Type' => 'movie', 'Title' => 'Thor', 'Year' => 2011},
      {'Type' => 'movie', 'Title' => 'Iron Man', 'Year' => 2008},
      {'Type' => 'series', 'Title' => 'Parks and Recreation', 'Year' => 2009},
      {'Type' => 'series', 'Title' => 'Friends', 'Year' => 1994},
    ]

    results = group_search_results(items)
    expect(results).to eq({
      'movie' => [
        {'title' => 'Thor', 'year' => 2011},
        {'title' => 'Iron Man', 'year' => 2008},
      ],
      'series' => [
        {'title' => 'Parks and Recreation', 'year' => 2009},
        {'title' => 'Friends', 'year' => 1994},
      ],
    })
  end
end

def组搜索结果(项目)
results=Hash.new{| Hash,key | Hash[key]=[]}
项目。每个带有_对象(结果)的|项目|
结果[项目['Type']]项目['Title'],'year'=>项目['year']}
终止
终止
描述“搜索结果”是什么
它“分组成一个对象”吗
项目=[
{'Type'=>'movie','Title'=>'Thor','Year'=>2011},
{'Type'=>'电影','Title'=>'钢铁侠','Year'=>2008},
{'Type'=>'系列','Title'=>'公园和娱乐','Year'=>2009},
{'Type'=>'系列','Title'=>'Friends','Year'=>1994},
]
结果=组搜索结果(项目)
期望(结果)达到均衡({
“电影”=>[
{'title'=>Thor','year'=>2011},
{'title'=>'钢铁侠','year'=>2008},
],
“系列”=>[
{'title'=>'公园和娱乐','year'=>2009},
{'title'=>'Friends','year'=>1994},
],
})
终止
终止

请为您的示例显示您想要的结果(Ruby对象)。那么,当您第一次尝试推送它时,您认为
@results['movie']
的值是多少?还有,你得到了什么错误?没有方法?@jvillian,我确实得到了结果,但它只给了我循环中的最后一项,我想要所有的结果items@CarySwoveland我想要的结果是我上面提到的JSON对象结构。我误解了。大概,
results
(而不是
@results
)是一个散列。这是什么?啊,非常感谢,这正是我要找的。你最好写
@results=Hash.new{h,k | h[k]=[]}
,让它更一般。例如,如果
@results
没有键
'movie'
@results['movie']
@results['movie']r['Title']中,'year'=>r['year']
将在
r['Title']之前设置为空数组,则执行'year'=>r['year']
。@CarySwoveland这是一个很好的观点。但是,只有当此代码旨在提供比OP需要的更通用的用例时,使其通用才有用。我同意,前提是crystal ball已经得出结论,哈希的键将来不会更改。
results =  { 
  search: { 
    movie: [
      { title: 'Thor', year: 2011 },
      { title: 'Iron Man', year: 2008 },
    ],
    tv: [
      { title: 'Parks and Recreation', year: 2009 },
      { title: 'Friends', year: 1994 },
    ]
  }
}

@results = Hash.new{|k, v| k[v] = []}
results[:search].each do |type, array| 
  @results[type].push(*array) 
end

results[:search].each_with_object(Hash.new{|k, v| k[v] = []}) do |(type, array), hash| 
  hash[type].push(*array) 
end