Mit Versionen gefülltest Array sortieren

Scorp1337

Erfahrenes Mitglied
Hi Leute,
leider funktioniert die asort() Funktion nicht :(
Ich habn array... gefüllt mit einigen Versionen und dieses soll nach den Werten sortiert werden.
PHP:
print_r($releases);
asort($releases);
echo "<br>";
print_r($releases);

Leider gibt dieser Code nachfolgende zwei Zeilen aus
Code:
Array ( [0] => 4.12.1.12 [1] => 4.12.1.13 [2] => 4.12.1.4 [3] => 4.12.1.5 [4] => 4.12.1.9 )
Array ( [0] => 4.12.1.12 [1] => 4.12.1.13 [2] => 4.12.1.4 [3] => 4.12.1.5 [4] => 4.12.1.9 )
Soll ich mir also die Arbeit machen und den Inhalt des Arrays manuell sortieren?
Eigentlich ist ja nachfolgende Reihenfolge richtig
4.12.1.4
4.12.1.5
4.12.1.9
4.12.1.12
4.12.1.13

Grüße,
Norman
 
Er nimmt die Angaben nicht als Zahlen sondern als Text und da ist 12, 15, 19 eben kleiner als 2.

Du müsstest die Zahlen immer mit führender 0 versehen, dann sollte es klappen.

Also quasi so:

4.12.1.04
4.12.1.05
4.12.1.09

Habe es getestet und muss mir Recht geben ;-)

Code:
Array ( [0] => 4.12.1.12 [1] => 4.12.1.13 [2] => 4.12.1.04 [3] => 4.12.1.05 [4] => 4.12.1.09 ) 
Array ( [2] => 4.12.1.04 [3] => 4.12.1.05 [4] => 4.12.1.09 [0] => 4.12.1.12 [1] => 4.12.1.13 )
 
Zuletzt bearbeitet:
Hi,

du wirst wohl nicht drum herumkommen dir selber etwas zu bauen. Du musst allerdings nicht den ganzen Sortieralgorithmus neu schreiben, sondern nur eine Funktion, die zwei Werte (Versionen) vergleicht und feststellt, welche in der Sortierreihenfolge nach vorne kommt:

PHP:
$data = array("4.12.1.12", "4.12.1.13", "4.12.1.9", "4.12.1.4");

usort($data, 'sortByLen');

function sortByLen($a, $b) {
   if (strlen($a) == strlen($b)) {
      return 0;
   } else {
      return (strlen($a) > strlen($b)) ? 1 : -1;
   }
}
Die obere Funktion sortiert das Array z.B. nicht nach Alphabet, sondern nach Zeichenkettenlänge.
Du müsstest es dann nur noch umschreiben, dass es die Versionen ($a und $b) analysiert und dann 1 zurückgibt, wenn Version $a größer als Version $b ist, bzw -1, wenn andersherum. Und 0 muss zurückgegeben werden, wenn beide Versionen identisch sind.

http://php.net/manual/de/function.usort.php

/edit: oder so wie tombe, wenn du die Möglichkeit hast, die Daten zu verändern :)
 
Ich habe schon vermutet, dass es die reine Text-Sortierung ist.

Leider muss ich dann also doch was bauen. Achja, gleiche gibt es nicht.
Lese diese Werte kurz vorher aus einer mySQL DB bei der das versions-Attribut UNIQUE ist.

Gruß,
Scorp

PS: Danke für die Hilfe******
 
Das ist jetzt eher eine konzeptionelle Frage, allerdings möchte ich dafür keinen extra Thread aufmachen.
(vielleicht sieht das ein Mod anders und verschiebts?)

Der User wählt zwei Versionen: 4.12.1.3 und 4.12.1.7. Es sollen jetzt alle Änderungen die dabei passiert sind angezeigt werden. Das bezieht sich also auf alle folgenden Releases:
4.12.1.3
4.12.1.4
4.12.1.5
4.12.1.6
4.12.1.7

In der DB stehen natürlich mehr 4.12.1er Releases. Ich lese aktuell alle Releases dieser Version mit folgender DB Abfrage aus:
PHP:
$arr1 = preg_split("/[0-9]{1,}$/", $v1); //Letzte Zahl abschneiden
$arr2 = preg_split("/[0-9]{1,}$/", $v2);
if($arr1[0] == $arr2[0]) {
	$qry = mysql_query("SELECT `ID`, `version` FROM `mvm`.`releases` WHERE `version` LIKE '" . $arr1[0] . "%'");
	while($row = mysql_fetch_assoc($qry)) {
		$releases[] = $row['version'];
	}
Erst mit $releases[] arbeite ich weiter und filtere dann auf die benötigten Releases. Meint ihr es gibt vieleicht eine bessere Variante der Abfrage bei der nur die relevanten abgefragt werden? (In der DB ist "version" natürlich ein varchar)
 
Schau mal ob das hier funktioniert:

SQL:
SELECT ID, version FROM mva.releases WHERE REPLACE(version, ".", "") BETWEEN 41213 AND 41217
 
Sah ziemlich vielversprechend aus... leider funktioniert es wohl nicht:
Code:
SELECT `ID`, `version` FROM `releases` WHERE REPLACE(`version`, ".", "") BETWEEN 41219 AND 412113;
liefert mir folgende Ergebnisse:
Code:
49	4.10.1.11
54	4.12.1.12
57	4.12.1.13
53	4.12.1.9
50	4.12.2.1

Also sobald die letzte Zahl unterschiedlich viele Ziffern hat gibt es Probleme.
 
Zuletzt bearbeitet:
Klar,
Code:
SELECT `ID`, `version` FROM `releases` WHERE REPLACE(`version`, ".", "") BETWEEN 41219 AND 412113;
unterscheidet ja auch nicht zwischen Version 4.1.12.3 und Version 4.1.1.23, beides wird zu 41123.

Was machst du denn wenn ein User Version 4.1.10.3 und Version 4.1.12.5 vergleichen will?

Du müsstest ja eigentlich von vorne angefangen die Strings der beiden Versionen zu vergleichen und den größten gemeinsamen Teil in dein LIKE packen. Im diesen Falle also "4.1.1"
Danach kannst du wie gehabt in php das Array ordnen und weitermachen.

/edit
Du solltest auf jeden Fall von vorne anfangen und nicht von hinten, denn sonst bekommst du Probleme, wenn du Version 4.1.10 und Version 4.1.12.4 verlgeichen willst (außer deine Versionen haben IMMER 4 Teile)...
/edit

Das in dein SQL-Query zu bauen halte ich für unmöglich oder nur sehr kompliziert und sooo viele unnötige Daten werden ja auch nicht übertragen. Du musst nur nachher in PHP die Versionen außen vor lassen, die kleiner als 4.1.10.3, bzw. größer als 4.1.12.5 sind.
 
Zuletzt bearbeitet:
Ein Vergleich ist ausschließlich versionsabhängig möglich sprich:
innerhalb: 4.11.1.x
4.12.1.x
4.12.2.x

Die Ausgabe wäre andernfalls viel zu groß. Kleine Erläuterung:
Code:
  4     .    12     .    1     .    22
major		minor     SrviceP	   Build

Ich kann bei bis zu 30 Builds oder sowas sicher nicht auch noch über Servicepacks oder Minor-Versionen vergleichen. Da würden aber tausende Änderungen rauskommen...
Die Ausgabe zeigt ja alle Änderungen (neue Dateien, gelöschte Dateien, kommentar bei Dateiänderung).

*edit
ja die Versionen werden nur ab jetzt eingetragen. Vor 4.10.1.1 gab es noch drei stellige Versionsnummern, allerdings werden die hierfür nicht berücksichtigt.
 
Und wie ist das hier:

SQL:
SELECT ID, version FROM releases WHERE SUBSTRING_INDEX(version, ".", 3) = "4.12.1" AND SUBSTRING_INDEX(version, ".", -1) BETWEEN 3 AND 7;
 
Zurück