2011-05-28 6 views
5

Estoy trabajando en una base de datos que manipula los resultados de exámenes de estudiantes universitarios. Básicamente, estoy extrayendo los registros de una base de datos MySq, pulsando una clase en un momento dado. Quiero clasificar el rango de los estudiantes, con el perfomer más alto en el número 1.
Aquí hay una ilustración;¿Cómo clasifico los valores de matriz con valores duplicados y omitiendo algunas posiciones si hay un empate?

Marks: 37, 92, 84, 83, 84, 65, 41, 38, 38, 84. 

Así que quiero capturar datos de mysql como una única matriz. Una vez que tengo los datos en una matriz, entonces debería asignar a cada alumno un puesto en la clase, como 1/10 (número 1, puntaje 92), 4/10, etc. Ahora el problema es que si hay un empate, luego, el siguiente puntaje se saltea una posición y si hay 3 puntajes en una posición, entonces la siguiente puntuación se salta 2 posiciones. Entonces los puntajes arriba se clasificarían de la siguiente manera;

92 - 1 
84 - 2, 
84 - 2, 
84 - 2, 
83 - 5, 
65 - 6, 
41 - 7, 
38 - 8, 
38 - 8 , 
37 - 10 

El sistema de clasificación requiere que el número de posiciones (rangos, si se quiere) se mantendrá, por lo que terminó con 10 posiciones en esta clase desde las posiciones 3, 4, 5 y 9 no tienen ningún ocupantes. (¡La alternativa de llenar cada número nos habrá dado solo 8 posiciones!)

¿Es posible (humanamente posible/php posible) usar PHP para clasificar los puntajes anteriores de tal manera que pueda manejar posibles vínculos como 4 puntajes en una posición? TAN SENCILLAMENTE, no pude idear una función para hacer esto. Necesito una función de PHP (o algo ... PHP) que tome una matriz y produzca una clasificación como la anterior.

Cualquier ayuda será profundamente apreciado, aunque creo que puedo estar pidiendo demasiado. Si es posible hacerlo con los datos de consulta de MySQL sin tenerlo en una matriz, ¡eso también será útil!

Respuesta

5

que asumen los grados ya están ordenados por la base de datos, de lo contrario usar sort($grades);.

Código:

$grades = array(92, 84, 84, 84, 83, 65, 41, 38, 38, 37); 
$occurrences = array_count_values($grades); 
$grades = array_unique($grades); 
foreach($grades as $grade) { 
    echo str_repeat($grade .' - '.($i+1).'<br>',$occurrences[$grade]); 
    $i += $occurrences[$grade]; 
} 

Resultado:

92 - 1 
84 - 2 
84 - 2 
84 - 2 
83 - 5 
65 - 6 
41 - 7 
38 - 8 
38 - 8 
37 - 10 

EDITAR(Respuesta a la discusión más adelante)

Al parecer, en caso de que ocurra el empate una t el puntaje más bajo,
el rango de todos los puntajes más bajos debe ser igual al recuento total de puntajes.

Código:

$grades = array(92, 84, 84, 84, 83, 65, 41, 38, 37, 37); 
$occurrences = array_count_values($grades); 
$grades = array_unique($grades); 
foreach($grades as $grade) { 
    if($grade == end($grades))$i += $occurrences[$grade]-1; 
    echo str_repeat($grade .' - '.($i+1).'<br>',$occurrences[$grade]); 
    $i += $occurrences[$grade]; 
} 

Resultado:

92 - 1 
84 - 2 
84 - 2 
84 - 2 
83 - 5 
65 - 6 
41 - 7 
38 - 8 
37 - 10 
37 - 10 
+0

Esto funciona muy bien hasta que termina el empate. En ese caso, la posición asignada a los últimos puntajes (los que empatan) no será igual al número total de puntajes. En el resultado anterior, verá que el puntaje 37 está posicionado en el número 10, lo que es útil ya que es el puntaje más bajo y resulta ser el número total de estudiantes. Sin embargo, si tenemos un empate en 37 (puntaje más bajo) y no 38, a los dos últimos puntajes se les asignará el puesto 9 en lugar de 10. Supongo que es necesario un condicional que verifique si un empate implica el puntaje más bajo, soy tratando de agregar tal condicional – Bululu

+0

Digamos que tenemos la siguiente matriz: '$ grades = array (92, 84, 84, 84, 83, 65, 41, 38, 37,37);' Ambos '37' aparecen en los resultados como '37 - 9', que es correcto porque el primer' 37 'se encuentra realmente en la novena posición. En conclusión: cuando el empate ocurre en el grado más bajo, el rango para cada grado más bajo es igual al rango de la primera ocurrencia del grado más bajo. En este caso '9'. ¿Derecha? – Anne

+0

Creo que su código debería resolver el problema tal como es. El razonamiento al asegurar que el último puntaje sea igual al número de estudiantes que participaron en el examen es algo defectuoso. Si el empate ocurre en cualquier lugar pero al final, el puntaje más bajo será igual al número total de estudiantes. Si es al final lo que no puede suceder, e IU concuerda con usted si el segundo anotador más bajo está ubicado en digamos, 9 como en el ejemplo, entonces el siguiente anotador debería obtener la siguiente posición DESDE que no hay puntaje después ese. Mientras tanto, muchas gracias por esta respuesta, ¡eres un Genio! – Bululu

1
$scores = array(92, 84, 84, 84, 83, 65, 41, 38, 38, 37); 
$ranks = array(1); 
for ($i = 1; $i < count($scores); $i++) 
{ 
    if ($scores[$i] != $scores[$i-1]) 
     $ranks[$i] = $i + 1; 
    else 
     $ranks[$i] = $ranks[$i-1]; 
} 
print_r($ranks); 
+0

@Bululu Como complemento del código stuken.yuri, quisiera señalar que puede obtener los datos de la base de datos ya solicitados, para que no tenga que ordenarlos a través de las funciones de php. – koressak

+0

Puedo obtenerlo ordenado de mysql agregando algunos parámetros a la consulta. ¿Estás diciendo que es posible manipular los datos en la medida descrita en mi pregunta? Saltarse algunas posiciones en caso de empate? Ese es un requisito que pensé que no se puede lograr agregando orden por DESC o ASC en una consulta. Estaré contento si puede explicar cómo puedo lograr este alto grado de búsqueda usando una consulta. – Bululu

+0

yuri, muchas gracias, su solución también resuelve el problema. – Bululu

0

que necesitaba para terminar con un mapa de valores para clasificar. Este método puede ser más eficiente para la pregunta original también.

public static function getGrades($grades) 
{ 
    $occurrences = array_count_values($grades); 
    krsort($occurrences); 

    $position = 1; 
    foreach ($occurrences as $score => $count) { 
     $occurrences[$score] = $position; 
     $position += $count; 

    } 

    return $occurrences; 
} 

Si print_r en $ ocurrencias se obtiene

Array 
(
    [92] => 1 
    [84] => 2 
    [83] => 5 
    [65] => 6 
    [41] => 7 
    [38] => 8 
    [37] => 10 
) 

Sobre la base de la respuesta original, por lo que gracias!

Cuestiones relacionadas