结构成员中具有散列的结构数组的最大值

时间:2014-09-17 19:23:50

标签: ruby

是否有任何其他方法可以迭代并将数据放入临时数组中以获取此数据结构中id和最大值的对:

Results_struct = Struct.new(:comp_class, :usage, :competitors)
Competitor_struct = Struct.new(:name, :id, :user_id, :gear, :run,
                           :run_points, :strike, :strike_points,
                           :total)

advanced_comps = Results_struct.new(:advanced, true, [])
intermediate_comps = Results_struct.new(:intermediate, true, [])

comp_el1 = Competitor_struct.new('John D.', '1', '1', nil, [], nil, [], nil, [], nil, nil)
comp_el1.run << {:id => '10', :result => 50, :points => 0}
comp_el1.run << {:id => '11', :result => 100, :points => 0}

comp_el2 = Competitor_struct.new('Jake F.', '2', '2', nil, [], nil, [], nil, [], nil, nil)
comp_el2.run << {:id => '10', :result => 70, :points => 0}
comp_el2.run << {:id => '11', :result => 70, :points => 0}

advanced_comps.competitors << comp_el1
advanced_comps.competitors << comp_el2

# Some other actions

我想

[{:id => '10', :result => 70}, {:id => '11', :result => 100}]

我查看了mapselect,但没有找到方法将其用于此目的。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

我真的不明白你的问题,但我会抓住它。

让我们首先定义一个Struct对象:

MyClass = Struct.new :id, :result
  #=> MyClass

我们有:

MyClass.class
  #=> Class
MyClass.instance_methods(false)
  #=> [:id, :id=, :result, :result=]
my_class = MyClass.new(1,2)
my_class.id
  #=> 1
my_class.result
  #=> 2
my_class.id = "cat"
  #=> "cat"
my_class.id
  #=> "cat"

到目前为止,我们所做的就是创建一个具有两个实例变量访问器的类和一个简单的initialize方法,与以下内容完全相同:

class MyClass
  attr_accessor :id, :result
  def initialize(id, result)
    @id = id
    @result = result
  end
end

MyClass.instance_methods(false)
  #=> [:id, :id=, :result, :result=]

此时我们可以忘记我们是如何创建这个类的。我们现在可以重新打开它并添加方法来改进其功能。

让我们添加实例方法hash以根据两个实例变量的值创建哈希:

class MyClass
  def hash
    { :id => @id, :result => @result }
  end
end

MyClass.instance_methods(false)
  #=> [:id, :id=, :result, :result=, :hash]

我们也可以在创建类MyClass时使用Struct::new的形式执行此操作:

MyClass = Struct.new(:id, :result) do
   def hash
    { :id => @id, :result => @result }
  end
end

MyClass.instance_methods(false)
  #=> [:id, :id=, :result, :result=, :hash]

我们现在可以创建一个包含与类MyClass实例关联的哈希的数组:

a = [[MyClass.new('10', 100).hash, MyClass.new('20', 10).hash],
     [MyClass.new('10', 200).hash, MyClass.new('20',  5).hash]]
  #=> [[{:id=>"10", :result=>100}, {:id=>"20", :result=>10}],
  #    [{:id=>"10", :result=>200}, {:id=>"20", :result=>5}]]

我不想理解你想要在数据结构中获得最大值的意思,但是一旦你拥有数组a,就应该很容易提取你想要的任何东西。例如,您可以通常的方式从此数组中提取元素:

[a[1][0], a[0][1]]
  #=> [{:id=>"10", :result=>200}, {:id=>"20", :result=>10}]

同样,如果对于a的每个元素,您希望哈希值为密钥:result的最大值,则可以执行此操作:

a.map { |b| b.max_by { |h| h[:result] } }
  #=> [{:id=>"10", :result=>100}, {:id=>"10", :result=>200}]

如果这不能回答你的问题,请告诉我。

答案 1 :(得分:0)

很简单,你只需要循环每个竞争者的每一轮。

我的建议是在循环期间临时转换数据结构,以便于操作:一个散列,其中每个条目都是id,结果是内容。

result=advanced_comps.competitors.inject({}) do |elem,comp|
  comp.run.each do |run| 
     elem[run[:id]]=[elem[run[:id]].to_f,run[:result]].max
  end elem
end

所以结果将包含这样的内容:

=> {"10"=>70, "11"=>100.0}

然后,如果你只想回到最初的结构:

result.map{|k,v|{:id=>k,:result=>v}}

=> [{:id=>"10", :result=>70}, {:id=>"11", :result=>100.0}]