PHP数组:“分组依据”然后计数最大值

I already asked this question for MySQL , but I want to do the same thing with a PHP array now.

|--------|------------|--------|
|  Name  |    Date    | Points |
|--------|------------|--------|
| Tom    | 2013-05-19 | 23     |
| Tom    | 2013-05-20 | 11     |
| Tom    | 2013-05-21 | 40     |
| Jack   | 2013-05-19 | 34     |
| Jack   | 2013-05-20 | 15     |
| Jack   | 2013-05-21 | 28     |
| Arthur | 2013-05-19 | 9      |
| Arthur | 2013-05-20 | 12     |
| Arthur | 2013-05-21 | 42     |
| Bill   | 2013-05-19 | 27     |
| Bill   | 2013-05-20 | 23     |
| Bill   | 2013-05-21 | 19     |
| ...    | ...        | ...    |

For a given person, I want to know how many times he got first and how many times he got last.

I tried several things like this :

<?php
    $req = $bdd->prepare('SELECT Name, Date, Points FROM quotes WHERE Date > ? AND Date < ?');
    $req->execute(array($_GET['datemin'], $_GET['datemax']));

    $retour=array();
    while ($donnees = $req->fetch(PDO::FETCH_ASSOC))
    {
        $retour[] = array('Date' => $donnees[Date], array(
            'Name' => $donnees[Name],
            'Points' => (float)$donnees[Points]
        ));

        // $key = array_search($donnees[Date], $retour);
        // var_dump($key);

        /*
        $retour[$i][] = array(
            'Name' => $donnees[Name],
            'Points' => (float)$donnees[Points]
        );
        */
    }

    $nb_first=0;
    $nb_last=0;

    // Input name : $_GET['id']

    /*
    foreach ($retour as $key_n1 => $value_n1) // Loop for each date
    {
        foreach ($value_n1 as $key_n2 => $value_n2) // For an unique day, compare the people's results
        {
            // Test here ?
        }
    }
    */

$send_value = array(
    'Nb_First' => $nb_first,
    'Nb_Last' => $nb_last
);

// var_dump($send_value);
echo json_encode($send_value);
?>

My idea was to use a 3-dimensional array by "grouping by" by date :

[01]
'Date' => '2013-05-19'
  | [01]
    | 'Name' => 'Tom'
    | 'Points' => '23'
  | [02]
    | 'Name' => 'Jack'
    | 'Points' => '34'
  | [03]
    | 'Name' => 'Arthur'
    | 'Points' => '9'
  | [04]
    | 'Name' => 'Bill'
    | 'Points' => '27'
[02]
'Date' => '2013-05-20'
  | [01]
    | 'Name' => 'Tom'
    | 'Points' => '11'
  | [02]
    | 'Name' => 'Jack'
    | 'Points' => '15'
[...]

Then, for each date, try to find if the given person ($_GET['id']) has the max value (then $nb_first++;) or the min value (then $nb_last++;).

Maybe there are some PHP functions that can help to do that. It's much easier to do that with a SQL query. :-(

Assuming that your array is something like the following:

$arr = array(   1 => array( 'Name'      => 'Tom',
                    'Date'      => '2013-05-19',
                    'Points'    => '23'),
        2 => array( 'Name'      => 'Tom',
                    'Date'      => '2013-05-20',
                    'Points'    => '11'),
        3 => array( 'Name'      => 'Tom',
                    'Date'      => '2013-05-21',
                    'Points'    => '40'),
        4 => array( 'Name'      => 'Jack',
                    'Date'      => '2013-05-19',
                    'Points'    => '34'),
        5 => array( 'Name'      => 'Jack',
                    'Date'      => '2013-05-20',
                    'Points'    => '15'),
        6 => array( 'Name'      => 'Jack',
                    'Date'      => '2013-05-21',
                    'Points'    => '28'),
        7 => array( 'Name'      => 'Arthur',
                    'Date'      => '2013-05-19',
                    'Points'    => '9'),
        8 => array( 'Name'      => 'Arthur',
                    'Date'      => '2013-05-20',
                    'Points'    => '12'),
        9 => array( 'Name'      => 'Arthur',
                    'Date'      => '2013-05-21',
                    'Points'    => '42'),
        10 => array('Name'      => 'Bill',
                    'Date'      => '2013-05-19',
                    'Points'    => '27'),
        11 => array('Name'      => 'Bill',
                    'Date'      => '2013-05-20',
                    'Points'    => '23'),
        12 => array('Name'      => 'Bill',
                    'Date'      => '2013-05-21',
                    'Points'    => '19'));

You can generate something similar to what you're looking for with:

$dates = array();
foreach ($arr as $key => $value){
    if (isset($dates[$value['Date']]['high'])){
        if ($value['Points'] >= $dates[$value['Date']]['high']){
            $dates[$value['Date']]['first'] = $value['Name'];
            $dates[$value['Date']]['high'] = $value['Points'];
        }
        if ($value['Points'] <= $dates[$value['Date']]['low']){
            $dates[$value['Date']]['last'] = $value['Name'];
            $dates[$value['Date']]['low'] = $value['Points'];
        }
    } else {
        $dates[$value['Date']]['first'] = $value['Name'];
        $dates[$value['Date']]['high'] = $value['Points'];
        $dates[$value['Date']]['last'] = $value['Name'];
        $dates[$value['Date']]['low'] = $value['Points'];
    }
    $dates[$value['Date']]['stats'][] = array(  'Name'      => $value['Name'],
                                                'Points'    => $value['Points']);
}