Philipp: Sortieren eines speziellen Arrays

Hi Ihr!

Ich bin gestern auf ein kleines Problem der Fubktion sort() bei PHP gestoßen.
Also ein richtiges Problem von der Funktion ansich ist es auch nicht.
Ich habe ein Array mit Werte, die unter anderem wie folgt aussehen können: =0.5, >32, =1, <=0.25, =16, =2, =4, =32, =8.

Richtig sortiert müsste es so aussehen: <=0.25, =0.5, =1, =2, =4, =8, =16, =32, >32.

Mit sort() sortiert sieht es aber leider so aus: <=0.25, =0.5, =1, =16, =2, =32, =4, =8, >32.

Habt ihr eine Idee, wie man solche Werte trozdem richtig sortiert bekommt?

Gruß,

Philipp

  1. hi,

    Mit sort() sortiert sieht es aber leider so aus: <=0.25, =0.5, =1, =16, =2, =32, =4, =8, >32.

    durchaus logisch.

    durch die zeichen wie = oder < und > sind es keine zahlen mehr, sondern strings.
    und die werden nunmal "alphabetisch" sortiert, und nicht nummerisch.

    gruss,
    wahsaga

    1. Hi

      durch die zeichen wie = oder < und > sind es keine zahlen mehr, sondern strings.
      und die werden nunmal "alphabetisch" sortiert, und nicht nummerisch.

      ja das leuchtet mir ja auch durchaus ein, aber einen Lösungsansatz hättest du auch nicht, oder?

      Gruß Philipp

      1. Moin!

        ja das leuchtet mir ja auch durchaus ein, aber einen Lösungsansatz hättest du auch nicht, oder?

        PHP hat ungefähr 10 Sortierfunktionen. Eine davon wird sicherlich passen.

        Untersuche insbesondere die Funktionen natsort() und usort().

        - Sven Rautenberg

        --
        SELFTREFFEN 2003 - http://selftreffen.kuemmi.ch/
        ss:) zu:) ls:[ fo:} de:] va:) ch:] sh:) n4:# rl:| br:< js:| ie:( fl:( mo:|
        1. Hi Sven,

          natsort() und usort() alleine haben es nicht gebracht.

          Habe jetzt eine kleine Fnktion geschrieben, die die Zeichen < <= = => > durch :1, :2, :3, :4, :5 am Ende des Wertes ersetzt.
          Diese Array kann ich jetzt mit natsort() natürlich sortieren lassen.
          Dabei kommt aber folgendes herraus:
          Array
          (
              [0] => 0.5:3
              [3] => 0.25:2
              [2] => 1:3
              [5] => 2:3
              [6] => 4:3
              [8] => 8:3
              [4] => 16:3
              [7] => 32:3
              [1] => 32:5
          )

          Meinem Verstand nach stimmen die beiden ersten Zahlen nicht, oder?????
          Ich habe es aus versucht, indem ich den "." durch "," ersetzt habe ...

          Vorschlag?

          Danke Philipp

          1. Moin!

            Hi Sven,

            natsort() und usort() alleine haben es nicht gebracht.

            Wenn natsort() es nicht bringt, mußt du usort() nehmen und dir eine eigene Sortierfunktion schreiben, welche jeweils zwei Werte vergleicht - nach _deinen_ Kriterien. Also die vorgehängten Zeichen ignoriert und die Zahl inklusive "Komma"-Punkt in eine Zahl wandelt und dann vergleicht.

            - Sven Rautenberg

            --
            SELFTREFFEN 2003 - http://selftreffen.kuemmi.ch/
            ss:) zu:) ls:[ fo:} de:] va:) ch:] sh:) n4:# rl:| br:< js:| ie:( fl:( mo:|
            1. Hi Sven.

              Wie würde denn dann die cmp-Funktion aussehen?! Kannst du mir das villeicht an einem, auf mein Problem bezogenen, Beispiel zeigen?
              Verstehe die Ausführung unter php.net nicht. Vielleicht bin ich auch einfach zu ddof zum Programmieren ;)

              Danke und Gruß

              Philipp

              1. Moin!

                Wie würde denn dann die cmp-Funktion aussehen?! Kannst du mir das villeicht an einem, auf mein Problem bezogenen, Beispiel zeigen?

                Das Beispiel für usort() liefert folgende Demo-Vergleichsfunktion:

                function cmp ($a, $b) {
                    if ($a == $b) return 0;
                    return ($a > $b) ? -1 : 1;
                }

                Das demonstriert eigentlich alles, was du zum Erstellen einer eigenen Funktion wissen mußt:

                1. Du kriegst zwei Elemente deines Arrays in den beiden Funktionsparametern, hier $a und $b genannt (die können aber auch anders heißen, wenn du willst).

                2. Du sollst als Funktionsergebnis Null zurückgeben, wenn beide Elemente gleich sind, du sollst -1 zurückgeben, wenn $a logisch _vor_ $b einsortiert werden soll, und du sollst 1 zurückgeben, wenn $a _hinter_ $b einsortiert werden soll.

                Logischerweise ist die Demo-Funktion sehr simpel.

                Deine Aufgabe ist es jetzt, eine Methode zu finden, die den Zahlenwert, der in den Strings drin ist (und der in $a und $b in deine Funktion hineinkommt), zu extrahieren, in eine Zahl umzuwandeln und diese Zahl dann mit dem anderen Wert zu vergleichen.

                Mit anderen Worten: Du kannst die Funktion eigentlich 1:1 übernehmen, du mußt vorher lediglich $a und $b so verändern, dass aus dem String ein Zahlenwert wird - der Vergleich selbst ist dann genau so, wie in der Funktion beschrieben.

                Also z.B. mit doubleval() http://de3.php.net/manual/de/function.doubleval.php jeweils $a und $b bearbeiten - keine Ahnung, ob das schon reicht. Ansonsten schneidest du mit einer anderen Stringfunktion einfach die ersten Zeichen ab, die keine Zahl sind.

                - Sven Rautenberg

                --
                SELFTREFFEN 2003 - http://selftreffen.kuemmi.ch/
                ss:) zu:) ls:[ fo:} de:] va:) ch:] sh:) n4:# rl:| br:< js:| ie:( fl:( mo:|
  2. Holladiewaldfee,

    Richtig sortiert müsste es so aussehen: <=0.25, =0.5, =1, =2, =4, =8, =16, =32, >32.

    Sortiere das Array zunächst ohne die Vergleichsoperatoren.
    Schau anschliessend nach, welche Einträge doppelt drin sind, ermittle die möglichen Operatoren der Einträge und hänge diese in der entsprechenden Reihenfolge vorne dran.
    Anschließend hängst Du die anderen Operatoren vorne dran.

    Ciao,

    Harry

    --
      Intelligenz ist nicht zwingend etwas positives.
      Man weiß erst, was man hatte, wenn man es verloren hat.