Der Aufbau eines „Kreuztabellen-“ oder „Drehpunkt“ -Tabelle aus einem Array in PHP

stimmen
4

Ich habe eine Reihe von Objekten, ähnlich wie die folgende Bedeutung haben:

$scores = array();

// Bob round 1
$s = new RoundScore();
$s->Round_Name = 'Round 1';
$s->Player_Name = 'Bob';
$s->Score = 10;
$scores[0] = $s;

// Bob round 2
$s = new RoundScore();
$s->Round_Name = 'Round 2';
$s->Player_Name = 'Bob';
$s->Score = 7;
$scores[1] = $s;

// Jack round 1
$s = new RoundScore();
$s->Round_Name = 'Round 1';
$s->Player_Name = 'Jack';
$s->Score = 6;
$scores[2] = $s;

// Jack round 2
$s = new RoundScore();
$s->Round_Name = 'Round 2';
$s->Player_Name = 'Jack';
$s->Score = 12;
$scores[3] = $s;

Wenn ich Schleife durch und das Dump - $scoresObjekt in eine Tabelle, wird es wie folgt aussehen:

Round_Name Spieler Score
----------------------------
Runde 1 Bob 10
Runde 2 Bob 7
Runde 1 Jack 6
Runde 2 Jack 12

Was ich will, ist jedoch etwas wie folgt aus:

Spieler Runde 1 Runde 2 Gesamt
-------------------------------
Bob 10 7 17
Jack 6 12 18

Ich werde nicht im Voraus wissen, wie viele Runden oder Spieler werden da sein und lasst uns einfach sagen, dass ich nicht die Art und Weise können die Objekte aufgebaut sind.

Was ist der effizienteste Weg, dies in PHP zu tun?

Veröffentlicht am 03/04/2009 um 01:50
quelle vom benutzer
In anderen Sprachen...                            


2 antworten

stimmen
6

Soweit ich das beurteilen kann, PHP Arrays werden als Hash-Tabellen (so Lookup / update sollte ziemlich effizient) wird die Effizienz sogar ein Problem, jedenfalls zeit umgesetzt?

Ich würde es nur tun, um den „einfachen“ Weg:

$table = array();
$round_names = array();
$total = array();

foreach ($scores as $score)
{
    $round_names[] = $score->Round_Name;
    $table[$score->Player_Name][$score->Round_Name] = $score->score;
    $total[$score->Player_Name] += $score->score;
}

$round_names = array_unique($round_names);

foreach ($table as $player => $rounds)
{
    echo "$player\t";
    foreach ($round_names as $round)
        echo "$rounds[$round]\t";
    echo "$total[$player]\n";
}

(Ich weiß, dass der Arrays nicht richtig initialisiert, aber Sie erhalten die Idee)

Beantwortet am 03/04/2009 um 03:09
quelle vom benutzer

stimmen
2

Wenn wir davon ausgehen, dass:

  • die Reihenfolge der Noten in der Anordnung ist immer in der Reihenfolge von Spielernamen und dann durch die runde Zahl
  • die Anzahl der Runden ist für jeden Spieler gleiche

Dann tun, was wir können, ist jeder Spieler die Partitur drucken, wie wir durch das Feld bewegt, während die Summe in den Prozess der Berechnung aber es Zurücksetzen, wenn wir einen neuen Spieler zu sehen:

$round_count = 0;
$header_printed = false;
$current_player = NULL;
$current_total = 0;
$current_output_line = "";
foreach ($scores as $score) {
    // Check whether we have to move to a new player
    if ($score->Player_Name != $current_player) {
        // Check whether we have anything to print before
        // resetting the variables
        if (!is_null($current_player)) {
            if (!$header_printed) {
                printf("%-10s", "Player");
                for ($i = 0; $i < $round_count; $i++) {
                    printf("%-10s", "Round $i");
                }
                printf("%-10s\n", "Total");

                $header_printed = true;
            }

            $current_output_line .= sprintf("%5d\n", $current_total);
            print $current_output_line;
        }

        // Reset the total and various variables for the new player
        $round_count = 0;
        $current_player = $score->Player_Name;
        $current_total = 0;
        $current_output_line = sprintf("%-10s", $score->Player_Name);
    }

    $round_count++;
    $current_total += $score->Score;
    $current_output_line .= sprintf("%5d     ", $score->Score);
}
// The last player is not printed because we exited the loop 
// before the print statement, so we need a print statement here.
if ($current_output_line != "") {
    $current_output_line .= sprintf("%5d\n", $current_total);
    print $current_output_line;
}

Beispielausgabe:

Player    Round 0   Round 1   Total
Bob          10         7        17
Jack          6        12        18

Dies sollte sehr effizient sein, weil es nur einmal durch das Feld geht.

Beantwortet am 03/04/2009 um 03:10
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more