Martin Hinrichs: Array nach Häufigkeit sortieren

Hallo,

ich hoffe, Ihr könnt mir bei einem Problem weiterhelfen. Ich habe ein Array, welches unsortierte Werte enthält. Dieses soll nun so sortiert werden (bzw. ein neues gebildet), dass die häufiger vorkommenden Werte am Anfang stehen. Etwa so:

array: 7,5,9,7,1,3,5,7,7,5,1

ergäbe dann (bei 4*7, 3*5, 1*9, 2*1, 1*3)

array: 7,5,1,9,3

Die doppelten Werte können also wegfallen, stattdessen müssen häufige Zahlen im Array weiter vorne stehen.

Mir will keine sinnvolle Lösung einfallen, für jede Hilfe bin ich dankbar.

Gruß,
Martin

  1. Hello,

    $_neues_array = array();

    foreach($_altes_array as $key=>$val)
      {
        $_neues_array[$val]++;
      }

    Harzliche Grüße aus http://www.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau
    1. hi,

      foreach($_altes_array as $key=>$val)
        {
          $_neues_array[$val]++;

      von dir als vertreter des peniblen, was PHP-fragen angeht, hätte ich mir jetzt aber wenigstens noch einen hinweis darauf gewünscht, dass $_neues_array[$val] beim ersten auftreten des wertes schlicht undefiniert ist, das ergebnis also streng genommen nicht vorhersehbar ist.

      auf existenz dieses keys abfragen, und wenn nicht vorhanden mit null initialisieren, wenn vorhanden hochzählen, wäre die sauberere variante.

      gruß,
      wahsaga

      --
      /voodoo.css:
      #GeorgeWBush { position:absolute; bottom:-6ft; }
      1. dass $_neues_array[$val] beim ersten auftreten des wertes schlicht undefiniert ist, das ergebnis also streng genommen nicht vorhersehbar ist.

        Falsch. Uninitialisierte Werte expandieren nach 0.

        1. hi,

          dass $_neues_array[$val] beim ersten auftreten des wertes schlicht undefiniert ist, das ergebnis also streng genommen nicht vorhersehbar ist.

          Falsch. Uninitialisierte Werte expandieren nach 0.

          korrigiere mich, wenn ich falsch liege - aber bei scharfem error_reporting würde PHP nichts desto trotz an dieser stelle beim erstmaligen auftauchen des keys eine notice schmeißen, oder?

          gruß,
          wahsaga

          --
          /voodoo.css:
          #GeorgeWBush { position:absolute; bottom:-6ft; }
          1. korrigiere mich, wenn ich falsch liege - aber bei scharfem error_reporting würde PHP nichts desto trotz an dieser stelle beim erstmaligen auftauchen des keys eine notice schmeißen, oder?

            Das ist korrekt. Ich habe auch nicht gesagt, eine Initialisierung wäre nicht der sauberere Weg. Nichtsdestotrotz expandiert undefiniert zu 0 bzw. '' bzw. Array(), je nach Kontext, das Ergebnis ist also alles andere als undefiniert sondern genau bekannt.

            Dass eine Notice 'rausgeworfen wird, hat andere Gründe. Das zugreifen auf nicht initialisierte Werte kann ein Programmierfehler sein. PHP möchte es so einfacher machen, Fehler zu finden.

            1. hi,

              Nichtsdestotrotz expandiert undefiniert zu 0 bzw. '' bzw. Array(), je nach Kontext, das Ergebnis ist also alles andere als undefiniert sondern genau bekannt.

              nur dieser punkt war mir unklar.
              in anderen sprachen können bei nichtinitialisierung von variablen ja durchaus zugriffe auf "irgendwelche" speicherstellen erfolgen, die dann ggf. datenmüll liefern.

              dass PHP hier gnädigerweise von 0, '' oder array() aufgeht, sehe ich auch mal wieder als zugeständnis an die einsteigerfreundlichkeit; mir war aber nicht bekannt, dass man dieses verhalten als verlässliches ansehen darf.
              kennst du auf anhieb eine stelle im manual, die dies beschreibt?

              gruß,
              wahsaga

              --
              /voodoo.css:
              #GeorgeWBush { position:absolute; bottom:-6ft; }
              1. in anderen sprachen können bei nichtinitialisierung von variablen ja durchaus zugriffe auf "irgendwelche" speicherstellen erfolgen, die dann ggf. datenmüll liefern.

                In Script-Sprachen ist das schon länger Gang und Gäbe so.

                dass PHP hier gnädigerweise von 0, '' oder array() aufgeht, sehe ich auch mal wieder als zugeständnis an die einsteigerfreundlichkeit;

                Naja. Sagen wir es so: Perl kann es, Python kann es, da darf PHP nicht hinterherhinken. Die Konkurrenz ist stark.

                kennst du auf anhieb eine stelle im manual, die dies beschreibt?

                Ja, die Seite über type juggling.

          2. Hello,

            korrigiere mich, wenn ich falsch liege - aber bei scharfem error_reporting würde PHP nichts desto trotz an dieser stelle beim erstmaligen auftauchen des keys eine notice schmeißen, oder?

            Nein, würde es nicht, da das Statement von links nach rechts abgearbeitet wird.
            Ist das Element nicht vorhanden, wird es implizit deklariert (mit Wert = NULL), dann hineingeschaut, was drinsteht und dann erst incrementiert. Da NULL, FALSE und 0 aber numerisch denselben Wert repräsentiern in PHP, ist das alles ganz sauber - as designed also!

            Harzliche Grüße aus http://www.annerschbarrich.de

            Tom

            --
            Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
            Nur selber lernen macht schlau
            1. Hello,

              und noch ein kliener Nachtrag
              Testscript:

              <?php    #### array_type.php ####

              Echo 'Typ von $_neu vor der Deklaration: '.gettype($_neu).'<br>';

              $_neu = array();

              echo 'Typ von $_neu nach der Deklaration: '.gettype($_neu).'<br>';

              echo 'Typ von $_neu[1] vor der Deklaration: '. gettype($_neu[1]).'<br>';

              ?>

              Ergibt:

              Typ von $_neu vor der Deklaration: NULL
              Typ von $_neu nach der Deklaration: array
              Typ von $_neu[1] vor der Deklaration: NULL

              Harzliche Grüße aus http://www.annerschbarrich.de

              Tom

              --
              Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
              Nur selber lernen macht schlau
    2. $_neues_array = array();

      foreach($_altes_array as $key=>$val)
        {
          $_neues_array[$val]++;
        }

      Ist das frustrierend. Meine Überlegung war locker 10 Zeilen lang. Respekt und vielen Dank!

    3. Hallo Tom,

      ~~~

      $_neues_array = array();

      foreach($_altes_array as $key=>$val)
        {
          $_neues_array[$val]++;
        }

        
      Wozu array\_count\_values( array input ) nachbauen, wenns das schon gibt?  
        
      Gruß  
      Alexander Brock
      
      -- 
      SelfCode: ie:{ fl:( br:> va:) ls:[ fo:) rl:( n4:? ss:| de:> js:( ch:| sh:( mo:} zu:}  
        
      <http://againsttcpa.com>
      
      1. Hello,

        Hallo Tom,

        ~~~

        $_neues_array = array();

        foreach($_altes_array as $key=>$val)
          {
            $_neues_array[$val]++;
          }

        
        >   
        > Wozu array\_count\_values( array input ) nachbauen, wenns das schon gibt?  
          
        Danke für den Hinweis.  
          
        Es könnten aber auch noch Randbedingungen fällig werden, so wie case insesitive, Umcodierung von Umlauten, eine Range, oder ähnliches und da ist es nicht ganz dumm, wenn man den Grundaufbau auch selber nachempfinden kann.  
          
          
        Harzliche Grüße aus <http://www.annerschbarrich.de>  
          
        Tom
        
        -- 
        Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen  
        Nur selber lernen macht schlau  
        
        
        1. Wozu array_count_values( array input ) nachbauen, wenns das schon gibt?

          Ein sehr guter Tipp, danke.

          Wenn Ihr noch eine Minute für mich habt wäre ich sehr dankbar.
          Die nun sortierte List ist schon sehr schön und ergibt etwa:

          id    erg
          1006: 6 Treffer
          1002: 4 Treffer
          1100: 4 Treffer
          1211: 1 Treffer

          Nun gibt es noch eine Anforderung:
          Wenn ids die gleiche Anzahl "Treffer" haben, dann sollen die mit der höheren Zahl vor den niedrigeren stehen, in diesem Fall also die id 1100 vor der id 1002 stehen.

          Und wiedereinmal habe ich keine Lösung wie sich das effizient angehen lässt.

          Ich danke Euch für jeden Rat.
          Martin

    4. Hello,

      $_neues_array = array();

      foreach($_altes_array as $key=>$val)
        {
          $_neues_array[$val]++;
        }

      Ich habe vielleicht vergessen zu erwähnen, dass ich nicht sonderlich fit in PHP bin.

      Nun bekomme ich ein Array, in dem nur die Häufigkeit der Zahlen gespeichert sind, aber ich finde die Zahlen selbst nicht. Oder was mache ich falsch?

      Danke, Martin

      1. hi,

        Nun bekomme ich ein Array, in dem nur die Häufigkeit der Zahlen gespeichert sind, aber ich finde die Zahlen selbst nicht.

        die zahlen selbst sind jetzt die schlüssel dieses arrays.

        gruß,
        wahsaga

        --
        /voodoo.css:
        #GeorgeWBush { position:absolute; bottom:-6ft; }
      2. Hi,

        Nun bekomme ich ein Array, in dem nur die Häufigkeit der Zahlen
        gespeichert sind, aber ich finde die Zahlen selbst nicht. Oder was
        mache ich falsch?

        nö, du schaust nur nicht richtig, in dem array das rauskommt steht in
        array[zahl] wie häufig sie vorkommt, sortierst du dieses dann kannst du
        über key() bzw. next() auf die zahlen zugreifen.

        MfG

      3. Ich habe es verstanden, vielen Dank für Eure Hilfe!

        Martin