Der Aufbau eines „Kreuztabellen-“ oder „Drehpunkt“ -Tabelle aus einem Array in PHP
-
23-08-2019 - |
Frage
Ich habe ein Array von Objekten definiert in ähnlicher Weise auf die folgenden:
$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 werfen den $scores
Objekt in eine Tabelle, ist es so etwas wie folgt aussehen:
Round_Name Player Score ---------------------------- Round 1 Bob 10 Round 2 Bob 7 Round 1 Jack 6 Round 2 Jack 12
Was ich will, ist aber so etwas wie folgt aus:
Player Round 1 Round 2 Total ------------------------------- Bob 10 7 17 Jack 6 12 18
Ich werde nicht im Voraus wissen, wie viele Runden oder Spieler werden da sein und sagen wir einfach, ich nicht die Art und Weise ändern, können die Objekte aufgebaut sind.
Was ist der effizienteste Weg, dies in PHP zu tun?
Lösung
Wenn wir davon ausgehen, dass:
- die Reihenfolge der Noten im Array ist immer in der Reihenfolge von Spielernamen und dann durch die runde Zahl
- die Anzahl der Runden ist das gleiche für jeden Spieler
Dann, was wir tun können, ist Druck jeder Punktzahl des Spielers, wie wir durch das Feld bewegt, während die Summe in den Prozess der Berechnung aber Zurücksetzen es, 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;
}
Beispiel für die Ausgabe:
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.
Andere Tipps
Soweit ich das beurteilen kann, PHP Arrays werden als Hash-Tabellen implementiert (so Nachschlag / update sollte ziemlich effizient sein) Wird die Effizienz sogar ein Problem der Zeit überhaupt?
würde ich es nur die „einfache“ Art und Weise:
$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)