Bir "çapraz tabloyu" Bina

2 Cevap php

Ben aşağıda benzer tanımlanan nesneleri bir dizi var:

$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;

Yoluyla ve bir tabloya $scores nesne dökümü ben döngü, bu gibi bir şey olacak olursa:

Round_Name   Player   Score
----------------------------
Round 1      Bob        10
Round 2      Bob         7
Round 1      Jack        6
Round 2      Jack       12

Benim istediğim, ancak, böyle bir şey olur:

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

Ben orada olmak ve Sadece ben nesneler inşa şeklini değiştirmek değil diyelim olacak kaç mermi veya oyuncular önceden bilmek için gitmiyorum.

Php bunu yapmak için en etkili yolu nedir?

2 Cevap

Diyelim ki eğer:

  • the order of scores in the array is always in the order by player's name and then by the round number
  • mermi sayısı her oyuncu için aynı

Sonra, ne yapabiliriz sürecinde toplam hesaplama ama biz yeni bir oyuncu görürseniz bunu sıfırlamak ederken biz dizi aracılığıyla hareket olarak her oyuncunun puan yazdırmak olduğunu:

$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;
}

Örnek çıktı:

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

Sadece bir kez dizi geçer, çünkü bu oldukça verimli olmalıdır.

As far as I can tell, PHP arrays are implemented as hash tables (so lookup/update should be pretty efficient) Will time efficiency even be a problem, anyway?

Ben sadece o "basit" bir şekilde yapardı:

$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";
}

(Ben dizileri düzgün başlatılmış değil biliyorum, ama fikir olsun)