What does Float::INFINITY do, and why does it work for this sorting method?

时间:2016-02-12 21:11:22

标签: ruby

I'm working my way through an online program learning Ruby and one of the challenges/lessons was to write a method that takes in an argument of a hash whose values are all numbers and returns the "key" corresponding to the lowest value.

I wrote the following code that passed the test and afterward was shown the "recommended" solution, which of course was much more efficient. Can someone walk me through the second version of the method below and tell me how it accomplishes the task?

For purposes of the challenge, I was not allowed to use any of the following methods:

$getCrimes = mysql_query("SELECT * FROM crimes ORDER BY crimeid ASC");
$thepost = $_POST['crimeid'];

if ($_POST['commit']) {
    $crimethingy = $_POST['crimeid'];
    $getArray = mysql_fetch_array(mysql_query("SELECT * FROM crimes WHERE crimeid = '$thepost'"));
    $theID = $getArray['crimeid'];
    $theName = $getArray['crimename'];
    if ($crimethingy > 0) {
        echo $theName;
    }
}

while ($crimeRows = mysql_fetch_array($getCrimes)) {
    $crime_id = $_POST['crimeid'];
    $crimeID = $crimeRows['crimeid'];
    $crimeName = $crimeRows['crimename'];
    $lowestPayout = $crimeRows['payoutlow'];
    $highestPayout = $crimeRows['payouthigh'];

    echo
    "
      <table cellpadding='2' cellspacing='1' width='75%' class='content-cell' align='center' style='margin-top: 5px; margin-bottom: 5px;'>
        <tr><td class='header'>Avaliability</td></tr>
        <tr><td class='content' style='height: 50px;'>
          <i style='font-size: 13px;'><center>$crimeName</center></i>
          <br>
          <i style='font-size: 11px;'><center>&pound;$lowestPayout - &pound;$highestPayout</center></i>
        </td></tr>
        <tr><td class='header'><input type='hidden' name='crimeid' value='$crimeID'>
        <input type='submit' name='commit' value='Commit' style='width: 100%' class='submit'></td></tr>
      </table>
    ";
}

My solution:

#keys
#values
#min
#sort
#min_by

Recommended solution:

def key_for_min_value(name_hash)

lowest_key = nil

if name_hash != {}
   value_array=name_hash.collect do |key,value|
     value
   end

   loop do
     swapped = false
     (value_array.length-1).times do |i|
        if value_array[i] > value_array[i+1]
          value_array[i], value_array[i+1] = value_array[i+1], value_array[i]
          swapped=true
        end
     end
     break if not swapped
   end

   name_hash.each do |key,value|
      if value == value_array.first
        lowest_key = key
      end
   end
end
lowest_key
end

1 个答案:

答案 0 :(得分:2)

The second solution works because your hash can't contain a value that is greater than Float::INFINITY so it's guaranteed to trigger the strUser === "5" condition at least once.

An alternative would be to set if and then in the condition do

lowest_value = nil

but it's not as elegant (and requires another check that will only be true the first iteration.

Another alternative would be to remove the first value in the hash and set that to if lowest_value.nil? || v < lowest_value , then loop through the rest.