Die zehn größten Werte in einem Array finden (Thema: PHP Beispiele)

Finden und sortiertes Zurückgeben der 10 größten Werte eines Arrays in PHP

1. Hinweis

Dieser Artikel ist nahezu identisch mit demjenigen unter „die zehn kleinsten Werte in einem Array finden” und muss entsprechend nicht gelesen werden, sofern der genannte bereits durchgearbeitet wurde. Einziger wesentlicher Unterschied ist die Verwendung von rsort() (absteigende Sortierung) statt sort() (aufsteigende Sortierung) im ersten Beispiel.

2. Per rsort() und array_slice()

Der einfachste Weg, die zehn größten Werte in einem Array zu finden, ist die Kombination aus rsort($array) und array_slice($array, $start, $length) anzuwenden. Über rsort() wird das Array absteigend sortiert (wer die Schlüssel beibehalten will verwendet arsort()). Nach der Sortierung werden mit array_slice() die zehn ersten Werte des sortierten Arrays extrahiert. Entsprechend müssen an array_slice() $start=0 und $length=10 übergeben werden. Wie zu sehen ist, lässt sich die Anzahl der zu findenden Werte leicht ändern, indem $length erhöht oder verringert wird.

PHP-Code
<?php
	$arr = array(11, 10, 2, 9, 8, 4, 7, 6, 5, 1, 3);
	
	$arr2 = $arr; // $arr2 als Kopie von $arr definieren, damit das urspruengliche Array nicht veraendert wird
	rsort($arr2); // absteigend sortieren
	$arr2 = array_slice($arr2, 0, 10); // die ersten zehn Werte des sortierten Arrays auslesen
	var_dump($arr2);
?>

HTML-Code
array(10) {
  [0]=>
  int(11)
  [1]=>
  int(10)
  [2]=>
  int(9)
  [3]=>
  int(8)
  [4]=>
  int(7)
  [5]=>
  int(6)
  [6]=>
  int(5)
  [7]=>
  int(4)
  [8]=>
  int(3)
  [9]=>
  int(2)
}


3. Mit foreach-Schleife

Die zehn größten Werte selbst zu suchen, ohne dabei rsort() zu verwenden, ist deutlich schwieriger. Im nachfolgenden Beispiel wird dazu mit einer foreach-Schleife über alle Werte im Array iteriert. Bei jeder Iteration wiederum wird der aktuelle Wert mit allen bisher gesammelten größten Werten verglichen. Ist er größer als einer der Werte, dann wird er vor diesem im Rückgabearray einsortiert. (Der Vergleich beginnt beim größten bisher gefundenen Wert, sodass die Reihenfolge am Ende korrekt ist.)

PHP-Code
<?php
	$arr = array(11, 10, 2, 9, 8, 4, 7, 6, 5, 1, 3);

	$out = array();
	$countToFind = 10;
	
	// ueber alle zu sortierenden Werte iterieren
	foreach ($arr as $val) {
		$added = false;
		// ueber alle bereits sortierten Werte iterieren und herausfinden,
		// ob der Wert vor einem einsortierten Wert eingefuegt werden muss
		foreach ($out as $key=>$val2) {
			// $val wird vor $val2 eingefuegt, wenn $val>$val2
			if ($val>$val2) {
				// neues out = alles vor $val2 + $val2 + alles nach $val2 (bis max 10 Elemente)
				$out = array_merge(array_slice($out, 0, $key), array($val), array_slice($out, $key, $countToFind-1-$key));
				$added = true;
				break;
			}
		}
		
		// Falls die Liste noch leer ist oder noch Platz hat
		// und der Wert nicht einsortiert wurde, wird er am Ende der Liste
		// eingefuegt
		if ((!isset($key) || $key<$countToFind-1) && !$added) {
			$out[] = $val;
		}
	}
	
	var_dump($out);
?>

HTML-Code
array(10) {
  [0]=>
  int(11)
  [1]=>
  int(10)
  [2]=>
  int(9)
  [3]=>
  int(8)
  [4]=>
  int(7)
  [5]=>
  int(6)
  [6]=>
  int(5)
  [7]=>
  int(4)
  [8]=>
  int(3)
  [9]=>
  int(2)
}


Kommentare (1)

Von neu nach alt
Das Erstellen neuer Kommentare ist aufgrund der Einführung der europäischen Datenschutz-Grundverordnung (DSGVO) derzeit deaktiviert.
Wir bitten um ihr Verständnis.
Die Variante mit dem Array ist eher schlecht, weil für jeden Testwert alle Werte aus dem Zwischenarray getetstet werden und weil das Array-Slice-Konstrukt sehr unübersichtlich zu lesen ist.
Besser wäre den Array am Anfang mit dem niedrigsten Wert aus den ersten zehn Daten zu füllen und eine Testvariable für den Kleinsten der großen Werte zu haben. So braucht man weniger Tests.
Sollte ein Wert auftauchen, der größer als der kleinste der größen Werte ist, würde man den neuen Wert per Schleife an die passende Stelle bubblen lassen.
Ein weiterer Vorteil des Vorgehens ist, dass Vorbereitung des test-Arrays und das Füllen des Testarrays in zwei Bereiche getrennt wird. Unter testgetriebener Entwicklung und unter Beachtung der CleanCode-Regeln würde ich für beide Teile sogar in zwei separate Methoden auslagern, die ich dann durch automatisierte Test abgesichern (bzw. deren Funktion beweisen) würde.
<?php
$arr = array(11, 10, 2, 9);

// höchstens 10 Maximale Werte
$countToFind = ((count($arr) >= 10) ?
10 :
count($arr));
$lastIndexToFind = $countToFind - 1;

// erster Wert wird Basis für gefüllten String
// Bestimmen den kleinensten aus den ersten werten, eventuell weniger als 10?
$test = ((isset($arr[0])) ? $arr[0] : null);
$max = (count($arr) > $countToFind ? $countToFind : count($arr));
for ($i = 1; $i < $max; $i++) {
if ($test > $arr[$i]) {
$test = $arr[$i];
}
}
// Fülle Testarray mit jkleinestn Wert
$out = array_fill(0, $countToFind, $test);

// ueber alle zu sortierenden Werte iterieren
foreach ($arr as $val) {
if ($val > $test) {
$top = true;
for ($i = $lastIndexToFind; $i > 0; $i--) {
if ($out[$i - 1] >= $val) {
$out[$i] = $val;
$test = $out[$lastIndexToFind];
$top = false;
break 1;
}
$out[$i] = $out[$i - 1];
}
// Wenn der Wert der größe ist
if ($top) {
$out[0] = $val;
}
}
}
var_dump($out);
?>
Output
array (size=4)
0 => int 11
1 => int 10
2 => int 9
3 => int 2
AnrnoNym (Gast) #
Um unsere Webseite für Sie optimal zu gestalten und fortlaufend verbessern zu können, verwenden wir Cookies. Durch die weitere Nutzung der Webseite stimmen Sie der Verwendung von Cookies zu. Weitere Informationen zu Cookies erhalten Sie in unserer Datenschutzerklärung. OK