Mehrdimensionales Array mehrfach sortieren

Microhome

Erfahrenes Mitglied
Hallo zusammen,

ich würde gern folgendes Array sortieren, und zwar jeweils absteigend nach 'matches', 'sets' und 'points'. Dabei soll der Key allerdings erhalten bleiben.

Code:
Array
(
    [1] => Array
        (
            [matches] => 3
            [sets] => 6
            [points] => 29
        )

    [2] => Array
        (
            [matches] => 1
            [sets] => 3
            [points] => -15
        )

    [3] => Array
        (
            [matches] => 2
            [sets] => 4
            [points] => 13
        )

    [4] => Array
        (
            [matches] => 0
            [sets] => 1
            [points] => -27
        )

    [5] => Array
        (
            [matches] => 1
            [sets] => 4
            [points] => -1
        )

    [6] => Array
        (
            [matches] => 2
            [sets] => 4
            [points] => 14
        )

    [7] => Array
        (
            [matches] => 2
            [sets] => 4
            [points] => -5
        )

    [8] => Array
        (
            [matches] => 1
            [sets] => 2
            [points] => -8
        )

)


Das gewünschte Ergebnis:

Code:
Array
(
    [1] => Array
        (
            [matches] => 3
            [sets] => 6
            [points] => 29
        )
		
	[6] => Array
        (
            [matches] => 2
            [sets] => 4
            [points] => 14
        )
		
	[3] => Array
        (
            [matches] => 2
            [sets] => 4
            [points] => 13
        )
		
	[7] => Array
        (
            [matches] => 2
            [sets] => 4
            [points] => -5
        )
		
	[5] => Array
        (
            [matches] => 1
            [sets] => 4
            [points] => -1
        )
		
	[2] => Array
        (
            [matches] => 1
            [sets] => 3
            [points] => -15
        )
		
	[8] => Array
        (
            [matches] => 1
            [sets] => 2
            [points] => -8
        )

    [4] => Array
        (
            [matches] => 0
            [sets] => 1
            [points] => -27
        )
)


Habt ihr eine Idee, wie ich das am geschicktesten hinbekomme? Wäre hierfür array_multisort() eine Möglichkeit?



Danke euch und beste Grüße!
 
Hi microhome,

für komplexere Arraystrukturen nehme ich da immer [phpf]uasort[/phpf] (man achte auf das a im Namen!), bei dem du eine eigene Callback-Funktion angeben kannst:

PHP:
// Dein Array
$arr = array(/* ... */);

uasort($arr, function ($a, $b) {
  return ($a['matches'] < $b['matches']) ? -1 : 1;
});
Dies sortiert allerdings nur nach matches.
Wie möchtest du denn genau nach allen drei sortieren? Nach deren Summe?
 
Hey ComFreek,

habe inzwischen eine Lösung gefunden, die mir zwar den Index zerschießt, da er numerisch ist, aber das ist nicht ganz so schlimm, da ich ich das entsprechende Feld als weiteren Key hinzufügen kann.

Das ganze funktioniert folgendermaßen:
Code:
foreach ($wins as $key => $row) {
	    $m[$key] = $row['matches'];
	    $n[$key] = $row['sets'];
	    $o[$key] = $row['points'];
	}

	array_multisort($m, SORT_DESC, $n, SORT_DESC, $o, SORT_DESC, $wins);

Dabei wird jeweils absteigend sortiert. Zuerst nach matches, dann nach sets und zuletzt nach points. Du kannst dir das vorstellen wie bei mehreren ORDER BY Deklarationen in einem MySQL Query.



Beste Grüße!
 
So behälst du deine Schlüssel bei.
PHP:
$array = array(
  1 => array('matches' => 3, 'sets' => 6, 'points' => 29),
  2 => array('matches' => 1, 'sets' => 3, 'points' => -15),
  3 => array('matches' => 2, 'sets' => 4, 'points' => 13),
  4 => array('matches' => 0, 'sets' => 1, 'points' => -27),
  5 => array('matches' => 1, 'sets' => 4, 'points' => -1),
  6 => array('matches' => 2, 'sets' => 4, 'points' => 14),
  7 => array('matches' => 2, 'sets' => 4, 'points' => -5),
  8 => array('matches' => 1, 'sets' => 2, 'points' => -8)
);
function inverse_cmp($a, $b){
  return $a==$b?0 : ($a > $b? -1 : 1);
}
function multisort($a, $b){
  $matches =  inverse_cmp($a['matches'], $b['matches']);
  if( $matches == 0 ){
    $sets =  inverse_cmp($a['sets'], $b['sets']);
	if( $sets == 0 ){
	  return  inverse_cmp($a['points'], $b['points']);	  
	}
	else{
	  return $sets;
	}
  }
  else{
    return $matches;
  }
 }
uasort($array, 'multisort');
echo '<pre>';
var_dump($array);
echo '</pre>';


Ausgabe:
Code:
array(8) {
  [1]=>
  array(3) {
    ["matches"]=>
    int(3)
    ["sets"]=>
    int(6)
    ["points"]=>
    int(29)
  }
  [6]=>
  array(3) {
    ["matches"]=>
    int(2)
    ["sets"]=>
    int(4)
    ["points"]=>
    int(14)
  }
  [3]=>
  array(3) {
    ["matches"]=>
    int(2)
    ["sets"]=>
    int(4)
    ["points"]=>
    int(13)
  }
  [7]=>
  array(3) {
    ["matches"]=>
    int(2)
    ["sets"]=>
    int(4)
    ["points"]=>
    int(-5)
  }
  [5]=>
  array(3) {
    ["matches"]=>
    int(1)
    ["sets"]=>
    int(4)
    ["points"]=>
    int(-1)
  }
  [2]=>
  array(3) {
    ["matches"]=>
    int(1)
    ["sets"]=>
    int(3)
    ["points"]=>
    int(-15)
  }
  [8]=>
  array(3) {
    ["matches"]=>
    int(1)
    ["sets"]=>
    int(2)
    ["points"]=>
    int(-8)
  }
  [4]=>
  array(3) {
    ["matches"]=>
    int(0)
    ["sets"]=>
    int(1)
    ["points"]=>
    int(-27)
  }
}
 
Zurück