Mario Lorenz: Array Sortier- und Manipulierproblem

Ich habe folgendes kniffliges Array-Problem:

In einem Array entsprechen die Schlüssel einer festen ID und die Werte eine "Sortierwertigkeit".

$array = array("0" => "12",
               "1" => "34",
               "2" => "35",
               "3" => "48",
               "4" => "78",
               "5" => "80");

Ich möchte nun, das ID 34 vor ID 78 gesetzt wird und damit das Array so manipuliert wird, das das Array dann im Ergebnis so aussieht:

("0" => "12",
               "1" => "35",
               "2" => "48",
               "3" => "34",
               "4" => "78",
               "5" => "80");

Mein Lösungsansatz war folgender:

Das Ur-Array via array_flip() vertauschen:

("12" => "0",
               "34" => "1",
               "35" => "2",
               "48" => "3",
               "78" => "4",
               "80" => "5");

Dann:

$array[34]=$array[78]-0.5;

Ergibt:

("12" => "0",
               "34" => "3.5",
               "35" => "2",
               "48" => "3",
               "78" => "4",
               "80" => "5");

Dann sortieren nach den Werten:

("12" => "0",
               "35" => "2",
               "48" => "3",
               "34" => "3.5",
               "78" => "4",
               "80" => "5");

Das Array via array_flip() wieder vertauschen und mittels array_values() die Schlüssel wieder auf ein glattes nummerisches Format bringen.

Ich bekomme nun leider beim zweiten array_flip() die Fehlermeldung, das ich nur Strings und Integers "flippen" kann.

Gibt es vielleicht einen besseren Lösungsansatz?

Vielen Dank,

Mario

  1. moins

    Dann sortieren nach den Werten:

    ("12" => "0",
                   "35" => "2",
                   "48" => "3",
                   "34" => "3.5",
                   "78" => "4",
                   "80" => "5");

    Das Array via array_flip() wieder vertauschen und mittels array_values() die Schlüssel wieder auf ein glattes nummerisches Format bringen.

    Ich bekomme nun leider beim zweiten array_flip() die Fehlermeldung, das ich nur Strings und Integers "flippen" kann.

    also ich hab im moment keinen besseren lösungsvorschlag, allerdings könntest du einfach mittels einer schleife neue ids zuweisen, damit hättest du aber keine festen ids mehr, was sie aber nach deiner lösung eh nicht wären

    sprich:

    $new_array=array();
    foreach($array as $key => $wert)
    {
     $new_array[]=$key;
    }

    letztendlich müsste es aber noch wesentlich einfach gehen, als der weg, den du hier angibst .... was auch immer du damit bezwecken willst ... viel spaß ;)

  2. hi,

    In einem Array entsprechen die Schlüssel einer festen ID und die Werte eine "Sortierwertigkeit".

    $array = array("0" => "12",
                   "1" => "34",
                   "2" => "35",
                   "3" => "48",
                   "4" => "78",
                   "5" => "80");

    Ich möchte nun, das ID 34 vor ID 78 gesetzt wird

    Welche ID 34 und welche ID 78?
    Ich dachte, die Schlüssel dieses Arrays wären deine IDs - also "0", "1", ... - und die Werte deine "Sortierwertigkeit"?

    und damit das Array so manipuliert wird, das das Array dann im Ergebnis so aussieht:

    ("0" => "12",
                   "1" => "35",
                   "2" => "48",
                   "3" => "34",
                   "4" => "78",
                   "5" => "80");

    Ich kann überhaupt keine logische Vorschrift erkennen, nach der aus obigem Array diese "Sortierung" hergestellt werden sollte.

    gruß,
    wahsaga

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }
  3. gudn tach!

      
    $put_val = 34;  
    $in_front_of_val = 78;  
    $put_key = $array_search($put_val, $array);  
    $in_front_of_key = $array_search($in_front_of_val, $array);  
      
    if($in_front_of_key < $put_key){  
      for($i=$put_key; $i>$in_front_of_key; --$i)  
        $array[$i] = $array[$i-1];  
      $array[$in_front_of_key] = $put_val;  
    }elseif($in_front_of_key > $put_key){  
      for($i=$put_key; $i<$in_front_of_key; ++$i)  
        $array[$i] = $array[$i+1];  
      $array[$in_front_of_key-1] = $put_val;  
    }else{  
      echo 'witzbold!'."\n";  
    }
    

    oder etwas kuerzer:

      
    $put_val = 34;  
    $in_front_of_val = 78;  
    $put_key = $array_search($put_val, $array);  
    $in_front_of_key = $array_search($in_front_of_val, $array);  
      
    $step = ($in_front_of_key<$put_key)? -1 : 1;  
    for($i=$put_key; $i!=$in_front_of_key; $i+$step)  
      $array[$i] = $array[$i+$step];  
    $array[$in_front_of_key-($step==1)] = $put_val;
    

    (ungetestet, aber die idee sollte anhand des ersten beispiels klar sein.)

    prost
    seth

    1. $step = ($in_front_of_key<$put_key)? -1 : 1;
                               ^ besser <=

      dann sollte es auch im fall $in_front_of_key==$put_key nicht schiefgehen.

      dass die zuordnung zwischen keys und values eine bijektion (eindeutig umkehrbar) sein muss, damit dein vorhaben funktioniert, weisst du vermutlich selbst. anmerken wollte ich's sicherheitshalber trotzdem noch.

      es kann uebrigens sein, dass deine urspruengliche idee, verknuepft mit dem vorschlag von SorgenkindMech (und vielleicht noch besser mit einem vorher "deklarierten" array), dennoch schneller ist. dazu muesste man sich den quellcode von php genauer anschauen.
      aber wenn es dir um performance ginge, wuerdest du vermutlich eh nicht zu php greifen. ;-)

      prost
      seth

    2. Liebe Freunde, die Tipps waren wie immer brauchbar. Vielen vielen Dank. Und hier die fertige Lösung:

        
      $sortstring  = "12,24,27,28,32,45";  
      $sortliste   = explode(',', $sortstring);  
      $wert1       = 45;    // Wert 1 soll  
      $vor_nach    = 1;  // vor (1) oder nach (2)  
      $wert2       = 27;    // Wer 2 platziert werden.  
        
      $sortliste2  = arraysort($sortliste, $wert1, $wert2, $vor_nach);  
        
      $sortstring2 = implode(',',$sortliste2);  
      echo $sortstring2;  
      exit();  
        
      function arraysort($sortarr, $schieb, $platz, $action){  
          $pos_schieb=array_search($schieb, $sortarr);  
          $pos_platz=array_search($platz, $sortarr);  
        
          if($pos_schieb<$pos_platz and $action==1){  
            for($x=0;$x<$pos_schieb;$x++){  
              $sortnew[]=$sortarr[$x];  
            }  
            for($x=$pos_schieb+1;$x<$pos_platz;$x++){  
              $sortnew[]=$sortarr[$x];  
            }  
            $sortnew[]=$schieb;  
            for($x=$pos_platz;$x<count($sortarr);$x++){  
              $sortnew[]=$sortarr[$x];  
            }  
          }  
        
          elseif($pos_schieb>$pos_platz and $action==1){  
            for($x=0;$x<$pos_platz;$x++){  
              $sortnew[]=$sortarr[$x];  
            }  
            $sortnew[]=$schieb;  
            for($x=$pos_platz;$x<$pos_schieb;$x++){  
              $sortnew[]=$sortarr[$x];  
            }  
            for($x=$pos_schieb+1;$x<count($sortarr);$x++){  
              $sortnew[]=$sortarr[$x];  
            }  
          }  
        
          elseif($pos_schieb<$pos_platz and $action==2) {  
            for($x=0;$x<$pos_schieb;$x++){  
              $sortnew[]=$sortarr[$x];  
            }  
            for($x=$pos_schieb+1;$x<$pos_platz+1;$x++){  
              $sortnew[]=$sortarr[$x];  
            }  
            $sortnew[]=$schieb;  
            for($x=$pos_platz+1;$x<count($sortarr);$x++){  
              $sortnew[]=$sortarr[$x];  
            }  
          }  
        
          elseif($pos_schieb>$pos_platz and $action==2){  
            for($x=0;$x<$pos_platz+1;$x++){  
              $sortnew[]=$sortarr[$x];  
            }  
            $sortnew[]=$schieb;  
            for($x=$pos_platz+1;$x<$pos_schieb;$x++){  
              $sortnew[]=$sortarr[$x];  
            }  
            for($x=$pos_schieb+1;$x<count($sortarr);$x++){  
              $sortnew[]=$sortarr[$x];  
            }  
          }  
          elseif($pos_schieb==$pos_platz){  
            $sortnew=$sortarr;  
          }  
          unset($sortarr);  
          return $sortnew;  
      }