2
I have an advanced report, which in the end processes the classification of the items, based on their score:
// Variável $relatório contém dados levantados e calculados em blocos para N itens. Cada bloco possui uma pontuação total do mesmo.
// Ex: $relatorio[0]['consolidado']['bloco_1']['total_pontos'], $relatorio[0]['consolidado']['bloco_2']['total_pontos'], $relatorio[0]['consolidado']['bloco_3']['total_pontos'], $relatorio[0]['consolidado']['bloco_N']['total_pontos'], ...
$classificacao_items = array();
foreach ($relatorio as $relatorio_item) {
$classificacao_items[] = array(
'cod_item' => $relatorio_item['item']['cod_item'],
'item' => $relatorio_item['item']['descricao'],
'etapa_num' => $relatorio_item['consolidado']['etapa_num'], // etapa_num é um índice do relatório consolidado que recebe um valor de 0 a 5 (varia de acordo com média de metas atingidas do item)
'pontos' => $relatorio_item['consolidado']['total_pontos'],
);
}
Currently, I raise the classification using the array Multisort
$classificacao_items = array_orderby($classificacao_items, 'etapa_num', SORT_ASC, 'pontos', SORT_DESC, 'item', SORT_ASC);
As you can see, I order first by etapa_num
, then by pontos
and finally by item
(Item name, alphabetical).
Snippet of the function:
/**
* Função de ordenação de arrays
* @see http://www.php.net/manual/en/function.array-multisort.php#100534
* @return mixed
*/
function array_orderby() {
$args = func_get_args();
$data = array_shift($args);
foreach ($args as $n => $field) {
if (is_string($field)) {
$tmp = array();
foreach ($data as $key => $row)
$tmp[$key] = $row[$field];
$args[$n] = $tmp;
}
}
$args[] = &$data;
call_user_func_array('array_multisort', $args);
return array_pop($args);
}
What I need now: if there is a point draw, I need to examine the sum of blocks (1 and 2 in the case) of the items and give a better ranking for an item (adding block 1 and 2), because the current tie-breaker parameter would be its name. That is, you would need to apply a custom function.
My problem is that I’m not being able to successfully apply this custom function. It ends up destroying the organization of items already correctly classified.
// Variável $items == variável $relatorio (descrito acima na introdução), ou seja, apenas com outro "apelido"
usort($classificacao_items, function($a, $b) use ($items) {
if ($a['pontos'] != $b['pontos']) // na lógica quando retorna 0 não é pra modificar a posição do item
return 0;
$relatorio_a = $items[$a['cod_item']]['consolidado'];
$relatorio_b = $items[$b['cod_item']]['consolidado'];
$notas_a = $relatorio_a['bloco_1']['total_pontos'] + $relatorio_a['bloco_2']['total_pontos'];
$notas_b = $relatorio_b['bloco_1']['total_pontos'] + $relatorio_b['bloco_2']['total_pontos'];
return $notas_a > $notas_b ? 1 : -1;
});
At the moment, I can’t see a viable solution to my problem. Every approach I try, I end up disorganizing with the array order. I need to apply this tiebreaker function only in cases that the score is equal and does not change what is right (with more or less score).
Functional and practical, more than accept solution!
– Julio Vedovatto
I’m happy to help!
– Miguel Angelo