Как упорядочить массив, используя вычисляемое значение, где остальные данные получены из базы данных mysql?

У меня есть страница под названием view.htm, которая отображает результаты в зависимости от того, что пользователь присваивает золотым, серебряным и бронзовым медалям, а также выбирает ли он использование ВВП или населения для расчета балла из view.php. Мне нужно найти способ упорядочить эти результаты по вычисленной оценке, а затем ограничить ее десяткой лучших. Мои данные получены из базы данных mysql, и оценка рассчитывается на странице php. Я использую json_encode для кодирования данных для отображения на странице. $results является двумерным массивом. Вот как выглядят результаты, когда вы выводите его из view.php:

{"gold":"0","silver":"0","bronze":"1","gdp":"20343461030","population":"34385000",  
"country_name":"Afghanistan","score":"0.029082448742184"},{"gold":"0",  
"silver":"0","bronze":"0","gdp":"12959563902","population":"3205000",  
"country_name":"Albania","score":"0"},{"gold":"1","silver":"0","bronze":"0",  
"gdp":"188681000000","population":"35468000","country_name":"Algeria",  
"score":"0.14097214390436"}

Ниже приведен php-код, который используется для расчета оценки:

$results = array();

while ($row = $res->fetchRow()){
    $resGold = $row['gold'];
    $resSilver = $row['silver'];
    $resBronze = $row['bronze'];
    $resGdp = $row['gdp'];
    $resPopulation = $row['population'];
    $resCountry = $row['country_name'];

    $gold_score = ($resGold * $gold_value);
    $silver_score = ($resSilver * $silver_value);
    $bronze_score = ($resBronze * $bronze_value);

    $total_medals = ($resGold + $resSilver + $resGold);
    $perMillion = $resPopulation/1000000;
    $perBillion = $resGdp/1000000000;

    $score_pop = (($gold_score + $silver_score + $bronze_score)/$perMillion);
    $score_gdp = ($perBillion/($gold_score + $silver_score + $bronze_score + 1));

    if($population == 'true'){ 
        $row['score'] = "$score_pop";
        array_push($results,$row);
    }

    else if($gdp == 'true'){ 
        $row['score'] = "$score_gdp"; 
        array_push($results,$row);
    }
}  

Любая помощь приветствуется. Спасибо


person dhruveonmars    schedule 08.05.2013    source источник


Ответы (2)


Я бы попытался рассчитать оценку на стороне базы данных и ограничить ее там. Что-то типа

select gold,silver,bronze,gdp,population,country_name,(gold * $gold_value + silver * $silver_value + bronze * $bronze_value) / (population / 1000000) as score from table sort by score desc limit 0,10

or

select gold,silver,bronze,gdp,population,country_name,(gdp / 1000000000) / (gold * $gold_value + silver * $silver_value + bronze * $bronze_value + 1) as score from table sort by score desc limit 0,10

в зависимости от численности населения и ВВП. В любом случае вы должны быть осторожны с объемом информации, содержащейся в таблице, и если производительность начнет ухудшаться, возможно, стоит сохранить отдельный столбец с предварительно рассчитанной оценкой, которая обновляется, когда остальная информация обновляется.

person jvilhena    schedule 08.05.2013

Вы должны иметь возможность сортировать результаты с помощью array_multisort, но Нам нужно создать массив результатов в виде списка. Поэтому, когда вы нажимаете свои результаты, также нажимайте на новый массив.

Сокращенно... по существу инициализируйте новый массив, и когда вы нажимаете на $results, также нажимаете на $scores

$results = array();
$scores = array();
while ($row = $res->fetchRow()){
   /* snipped */
   array_push($results,$row);
   array_push($scores,$score_pop);
}

array_multisort($scores, SORT_ASC, $results);

И рабочий пример (который я действительно тестировал)

    $result = array(
            array("name" => "guy", "score" => 30),
            array("name" => "dude", "score" => 1),
            array("name" => "bro", "score" => 20),
    );

$scores = array();
    foreach ($result as $r) {
            array_push($scores,$r['score']);
    }

array_multisort($scores,SORT_ASC,$result);

    print_r($result);

(Мои извинения за табы/пробелы)

person dougBTV    schedule 08.05.2013