【问题标题】:Ruby: Sorting 2 arrays using values from one of themRuby:使用其中一个数组的值对 2 个数组进行排序
【发布时间】:2012-04-17 16:07:46
【问题描述】:

我正在用 ruby​​ 创建一个简单的游戏,我有两个存储高分的数组:$HS_Points$HS_Names。我将高分保存在两个文件中,我想对点进行一点编码(这些点用.to_s(23) 转换)。我想按降序对名称和分数进行排序,并将它们限制为 10。所以,我需要:

  • 检查玩家得分是否高于高分(索引 0 到 9)。
  • 如果收到的分数足以让玩家进入前 10 名,请将分数和姓名放在该位置,将其他位置降低一位。

简单的points_array.sort 不行,因为它只会对点进行排序,让名称按原来的顺序排列。

任何想法如何解决这个问题?我希望尽可能简单地回答。

【问题讨论】:

    标签: ruby arrays sorting


    【解决方案1】:

    不要将名称和分数存储在单独的变量中;它们是绑定在一起的,所以它们的数据应该绑定在一起。

    试试 $HighScores,它是一个包含一个 :name 元素和一个 :value 元素的哈希数组,例如:

    $HighScores = [  
       { :name => "Bob", :score => 234 },
       { :name => "Mark", :score => 2 },   
    ]
    

    那你就可以加个高分了:

    $HighScores << { :name => "New Guy", :score => 50000 }
    

    然后将它们重新排序并在一个语句中取前 10 名:

    $HighScores = $HighScores.sort { |a,b| b[:score] <=> a[:score] }[0,10] 
    

    如果分数是 base-23 编码的,这仍然有效。 (但你为什么要这样做?)

    您可能还应该将它们保存到一个文件中。为简化此操作,请考虑使用 Marshal 模块。

    【讨论】:

    • 工作正常,只需要一件事:如何显示它们?之前用"#{$HS_Names[7]}: #{$HS_Points[7]}",现在明显不行了。
    • 这将转换为:“#{$HighScores[7][:name]}: #{$HighScores[7][:score]}”
    • 给我一个错误in '[]': can't convert Symbol into Integer &lt;TypeError&gt;
    • 也许变量不是我上面定义的确切格式?从这里我看不出来,但我的 sn-p 中看不到错误。
    【解决方案2】:

    这样的?

    names = ['Alice', 'Bob', 'Carol']
    points = [22, 11, 33]
    

    压缩

    您可能需要Array#zip 方法:

    pairs = names.zip(points)
    #=> [["Alice", 22], ["Bob", 11], ["Carol", 33]]
    

    排序

    要按数组字段排序,请比较该对的两个字段。

    按名称排序:

    pairs.sort{|x,y| x[0] <=> y[0] }  
    #=> [["Alice", 22], ["Bob", 11], ["Carol", 33]]
    

    按分数排序:

    pairs.sort{|x,y| x[1] <=> y[1] }  
    #=> [["Bob", 11], ["Alice", 22], ["Carol", 33]]
    

    排序方式

    另一种排序方法是#sort_by 方法而不是比较块(感谢 Niklas B.)

    按名称排序:

    pairs.sort_by(&:first) 
    #=> [["Alice", 22], ["Bob", 11], ["Carol", 33]]
    

    按分数排序:

    pairs.sort_by(&:last)
    #=> [["Bob", 11], ["Alice", 22], ["Carol", 33]]
    

    选择

    只选择高分以上的玩家:

    pairs.select{|x| x[1] >20 }
    #=> [["Alice", 22], ["Carol", 33]]
    

    解压

    解压:

    pairs.map(&:first)
    #=> ["Alice", "Bob", "Carol"]
    
    pairs.map(&:last)
    #=> [22, 11, 33]
    

    这些想法可能会为您指明正确的方向。

    【讨论】:

    • sortsn-p 也可以写成pairs.sort_by(&amp;:last)
    • @joelparkerhenderson 除了排序之外的所有工作。我试图输入值,当我在排序后打印出数组时:set.sort{|x,y| x[1] &lt;=&gt; y[1] } p set' And I received this: [["One", 100000], ["Two", 80000], ["Three", 50000], ["Four", 30000 ], ["Testing", 245132]]` "Testing" 和 245132 是我发送来测试它的值。另外,如何将压缩后的数组分成两部分(一个带有名称,第二个带有点)?
    • 当你“排序”时,它会对输出进行排序;它不会改变输入数组。因此,当您编写“p set”时,您实际上是在说“打印原始数组”。一种解决方案是使用“排序!”改变原始数组的方法;另一种解决方案是将结果存储在不同的变量中,例如high_scorers = ...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    • 2011-06-06
    • 2021-02-18
    • 1970-01-01
    相关资源
    最近更新 更多