hawkmaster: Bestimmte Array Werte löschen

Hallo zusammen,

Ich habe ein assoziatives Array das als Beispiel folgende Schlüssen hat:

Auto#@#Porsche
Haus#@#Stadt
Porsche#@#Auto
Stadt#@#Haus

Es gibt also immer einen "umgekehrten" Schlüssel

Diese Schlüssel mit den Werten möchte ich gerne löschen.
Ich habe so versucht:

$allkeys = array_keys($main_arr);
foreach($allkeys as $key){
 $check = explode("#@#",$key);
 $reversekey = $check[1]. "#@#" . $check[0];

unset($allkeys[$reversekey]);
}

Irgendwie klappt das aber nicht.
Gibt es eine einfachere Lösung?

vielen Dank und viele Grüße
hawk

  1. Hi,

    Das funktioniert nicht weil du mit
    unset($allkeys[$reversekey]);

    nur den Inhalt und nicht die schlüssel aus dem Array auf NULL setzt.

    --
    Selfcode: ie:{ fl:( br:> va:| ls:& fo:| rl:? n4:& ss:| de:/ js:} mo:) zu:}
    1. Hallo Robert,
      danke dir,

      Das funktioniert nicht weil du mit
      unset($allkeys[$reversekey]);
      nur den Inhalt und nicht die schlüssel aus dem Array auf NULL setzt.

      hmm, und wie macht man es dann richtig? Also das der entsprechende Key und die dazugehörigen Werte gelöscht werden?

      vielen Dank und viele Grüße
      hawk

      1. Hi,

        Muss mich korrigieren (zumindestens ergänzen) PHP schmeisst nähmlich
        ein key mit dem wert null raus, also kannst du das schon nehmen.

        din fehler lag bei der auswahl des arrays, probiers mal so:

        $allkeys = array_keys($main_arr);
        foreach($allkeys as $key => $value){
         $check = explode("#@#",$value);
         $reversekey = $check[1]. "#@#" . $check[0];

        unset($main_arr[$reversekey]);
        }

        print_r($main_arr);

        --
        Selfcode: ie:{ fl:( br:> va:| ls:& fo:| rl:? n4:& ss:| de:/ js:} mo:) zu:}
        1. Hallo Robert,

          din fehler lag bei der auswahl des arrays, probiers mal so:

          $allkeys = array_keys($main_arr);
          foreach($allkeys as $key => $value){
          $check = explode("#@#",$value);
          $reversekey = $check[1]. "#@#" . $check[0];

          unset($main_arr[$reversekey]);
          }

          print_r($main_arr);

          Hmm, jetzt wird irgendwie alles gelöscht.
          Die Ausgabe ist nur:

          Array ( )

          vielen Dank und viele Grüße
          hawk

          1. Hmm, jetzt wird irgendwie alles gelöscht.

            klar, die erste hälfte löscht die zweite und die zweite die erste :D

            foreach($main_arr as $key => $value)
            {
              $check = explode("#@#",$value);
              $reversekey = $check[1]. "#@#" . $check[0];
              unset($main_arr[$reversekey]);
            }

            achtung, ungetestet.

            Gruß,
            Niklas

            1. Hallo Niklas,
              danke auch dir für deine Hilfe.

              foreach($main_arr as $key => $value)
              {
                $check = explode("#@#",$value);
                $reversekey = $check[1]. "#@#" . $check[0];
                unset($main_arr[$reversekey]);
              }

              Leider klappt auch deine Variante nicht.

              Wenn ich danach;
              foreach($main_arr as $key => $value){
              ...
              }
              laufen lasse, sind immer noch alle Werte und Schlüssel drin.
              Es kann ja auch eigentlich nicht sein, weil bei deiner Variante der "Explode" auf die Values gemacht wird und nicht auf die Schlüssel.

              vielen Dank und viele Grüße
              hawk

              1. laufen lasse, sind immer noch alle Werte und Schlüssel drin.
                Es kann ja auch eigentlich nicht sein, weil bei deiner Variante der "Explode" auf die Values gemacht wird und nicht auf die Schlüssel.

                jo klar, natürlich musst du $key statt $value nehmen sry (:

                1. Hallo

                  jo klar, natürlich musst du $key statt $value nehmen sry (:

                  Tja das habe ich natürlich gleich ausgebessert aber dann sind wir wieder bei der Ausgangssituation, nämlich dass alles gelöscht wird bzw. das Array leer ist.
                  Ich glaube irgendwie geht das so nicht.
                  hmmm..

                  vielen Dank und viele Grüße
                  hawk

                  1. Ich glaube irgendwie geht das so nicht.
                    hmmm..

                    meiner meinung nach sollte er nur bestehende keys durchlaufen. die überlegung war, dass er dann die zweite, gelöschte hälfte gar nicht mehr durchläuft, aber falsch gedacht anscheinend. in dem fall eine for schleife mit zähler nehmen um das array durchzugehen

                    1. Tach.

                      meiner meinung nach sollte er nur bestehende keys durchlaufen. die überlegung war, dass er dann die zweite, gelöschte hälfte gar nicht mehr durchläuft, aber falsch gedacht anscheinend.

                      Was daran liegt, daß foreach mit einer Kopie des Arrays arbeitet.

                      --
                      Once is a mistake, twice is Jazz.
            2. Hello,

              Das sieht schon fast gut aus.
              Es muss nach dem explode() allerdings auch geprüft werden, ob es zwei Teile ergeben hat!

              Hmm, jetzt wird irgendwie alles gelöscht.

              klar, die erste hälfte löscht die zweite und die zweite die erste :D

              foreach($main_arr as $key => $value)
              {

              $check = explode("#@#",$key);        ## hier hattest Du versehentlich $value benutzt

              if ( count($check) ==2))             ## wenn es nicht zwei Teile gibt, ist kein '#@#'
                    {                                    ## drin gewesen im key
                        $reversekey = $check[1]. "#@#" . $check[0];
                        unset($main_arr[$reversekey]);
                    }
                }

              ebenfalls ungetestet.

              Ein harzliches Glückauf

              Tom vom Berg

              --
              Nur selber lernen macht schlau
              http://bergpost.annerschbarrich.de
              1. Hallo Tom,

                auch dir herzlichen Dank für deine Hilfe.

                foreach($main_arr as $key => $value)
                {
                      $check = explode("#@#",$key);        ## hier hattest Du versehentlich $value benutzt

                if ( count($check) ==2)             ## wenn es nicht zwei Teile gibt, ist kein '#@#'
                      {                                    ## drin gewesen im key
                          $reversekey = $check[1]. "#@#" . $check[0];
                          unset($main_arr[$reversekey]);
                      }
                  }

                leider klappt auch diese Variante nicht bzw. auch hier wird wieder das ganze Array gelöscht. Eine Ausgabe mit print_r($main_arr) hinterher bringt nur
                Array()
                Ich glaube ich muss mir eine andere Lösung überlegen.

                vielen Dank und viele Grüße
                hawk

                1. Hello,

                  auch dir herzlichen Dank für deine Hilfe.

                  Bitte, war aber leider "auf die Schnelle" und nicht zuende gedacht...

                  Ist doch irgendwie logisch, dass das hier mit dem einfachen foreach() nicht funktioniert, da ja bei diesen "chiasmsichen Doubletten" auf jeden Fall beide Versionen geprüft werden.

                  wenn "a#B" enthalten ist, wird auf jeden Fall "B#a" gelöscht.
                  Ist auch "B#a" enthalten, wird ebenfalls "a#B" gelöscht, egal, ob es nun nur noch alleine, alo ohne seinen Komplementär, im Stammarray steht. Das liegt daran, dass PHP im Kopf von Foreach() mit einer Kopie des Arrays arbeite, im Körper dann aber wieder mit dem Original.

                  Möglicher Lösungsweg wäre also, immer mit dem Original zu arbeiten.
                  Mit den Werten ist das inzwischen (seit PHP 5.x) möglich, ob es auch it dem gesamten Array bzw. den Keys funktioniert, habe ich noch nicht ausprobiert.

                  Eine stabile Lösung für Dich, die dann sowohl mit PHP4 als auch mit PHP5.x funktionieren sollte, denke ich mir gelich mal aus.

                  Was Du da machst, sieht zwar nicht unbedingt sinnvoll aus, ist aber trotzdem eine interessante Densportaufgabe...

                  Schau also später nochmal rein, dann habe ich eine Lösungsmöglichkeit auch _ausprobiert_ ;-))

                  Ein harzliches Glückauf

                  Tom vom Berg

                  --
                  Nur selber lernen macht schlau
                  http://bergpost.annerschbarrich.de
                  1. Hello,

                    Was Du da machst, sieht zwar nicht unbedingt sinnvoll aus, ist aber trotzdem eine interessante Densportaufgabe...

                    Schau also später nochmal rein, dann habe ich eine Lösungsmöglichkeit auch _ausprobiert_ ;-))

                    Habe gerade erst gesehen, dass Robert das Rätsel es schon gelöst hat...
                    Dann brauche ich das nicht noch einmal zu tun

                    Ein harzliches Glückauf

                    Tom vom Berg

                    --
                    Nur selber lernen macht schlau
                    http://bergpost.annerschbarrich.de
                    1. Hallo Tom,
                      dir auch nochmals vielen Dank für deinen Einsatz.
                      Ja die Variante von Robert funktioniert.
                      Interessant wäre es nochfür mich ob man nicht doch schon beim Lesen in die Datenbank diese "Doubletten" vermeiden könnte.
                      Dann wäre da auch nicht so viel Müll drin.

                      Siehe mein Posting hier:
                      http://forum.de.selfhtml.org/my/?t=173961&m=1142695

                      vielen Dank und viele Grüße
                      hawk

                      1. Hello,

                        Interessant wäre es nochfür mich ob man nicht doch schon beim Lesen in die Datenbank diese "Doubletten" vermeiden könnte.
                        Dann wäre da auch nicht so viel Müll drin.

                        Das Ganze sieht so interessant aus, dass man ja kaum wagt danach zu fragen, ob nicht bereits am darunterliegenden Konzept etwas falsch ist. Aber ich wage es trotzdem:

                        Ist vieleleicht schon am darunterliegenden Kpnzept etwas falsch? Woher kommen die Daten? Könnte man bei der Erfassung / Erstellung der Textdatei eventuell schon eingreifen?
                        Warum liegen die Daten in einer Textdatei vor und nicht in einer Datenbank oder tabellarischen Darstellung (Random Access File)?

                        Ist die mögliche Wertemenge bekannt, also beschränkt, oder handelt es ich um unbekannte Daten (eine unbeschränkte Ausgangsmenge)?

                        Ein harzliches Glückauf

                        Tom vom Berg

                        --
                        Nur selber lernen macht schlau
                        http://bergpost.annerschbarrich.de
                        1. Hallo Tom,

                          Ist vieleleicht schon am darunterliegenden Kpnzept etwas falsch? Woher kommen die Daten? Könnte man bei der Erfassung / Erstellung der Textdatei eventuell schon eingreifen?
                          Warum liegen die Daten in einer Textdatei vor und nicht in einer Datenbank oder tabellarischen Darstellung (Random Access File)?

                          Ist die mögliche Wertemenge bekannt, also beschränkt, oder handelt es ich um unbekannte Daten (eine unbeschränkte Ausgangsmenge)?

                          Ich habe dir mal eine genaue Beschreibung an deine Mail gesendet da es hier vermutlich zuviel wäre.

                          vielen Dank und viele Grüße
                          hawk

                          1. Hello,

                            Ich habe dir mal eine genaue Beschreibung an deine Mail gesendet da es hier vermutlich zuviel wäre.

                            Das sehe ich dann frühestens heute Abend...

                            Ein harzliches Glückauf

                            Tom vom Berg

                            --
                            Nur selber lernen macht schlau
                            http://bergpost.annerschbarrich.de
          2. Hi,

            $allkeys = array_keys($main_arr);
            foreach($allkeys as $key => $value){
            $check = explode("#@#",$value);
            $reversekey = $check[1]. "#@#" . $check[0];

            unset($main_arr[$reversekey]);
            }

            print_r($main_arr);

            Hmm, jetzt wird irgendwie alles gelöscht.

            Natürlich wird hier alles gelöscht, weil imprinzip dein gesammtes array rekursiv ist.

            wenn du nur die doppelten löschen möchtest musst du die einträge vergleichen
            und dann nur einen löschen.

            so hier z.B.:

            $allkeys = array_keys($main_arr);
            $tmp = array();
            foreach($allkeys as $key => $value)
            {
              $check = explode("#@#",$value);
             $reversekey = $check[1]. "#@#" . $check[0];
             if (array_key_exists($reversekey,$main_arr) && !array_key_exists($reversekey,$tmp))
             {
              $tmp[$value] = 1;
              unset ($main_arr[$reversekey]);
             }
            }

            print_r($main_arr);

            --
            Selfcode: ie:{ fl:( br:> va:| ls:& fo:| rl:? n4:& ss:| de:/ js:} mo:) zu:}
            1. Hallo Robert,

              herzlichen Dank:
              Deine Lösung war die richtige und jetzt nachträglich betrachtet wurde mir auch klar was mein Fehler war.

              vielen Dank und viele Grüße
              hawk

              1. Hi,

                nichts zu danken,
                aber unterlasse in Zukunft die doppelposts.

                --
                Selfcode: ie:{ fl:( br:> va:| ls:& fo:| rl:? n4:& ss:| de:/ js:} mo:) zu:}
                1. Siehst du das wirklich auch als doppelpost?
                  Es geht doch eigentlich um ganz unterschiedliche Dinge oder?
                  Hier Array Schlüssel vergleichen und bei der anderen Frage ging es um eine Textdatei einlesen und filtern und ums schreiben in eine DB.

                  Aber ok, ich lasse mich gerne belehren und achte in Zukunft noch mehr auf das Thema

                  viele Grüße
                  hawk

                  1. Hi,

                    Siehst du das wirklich auch als doppelpost?

                    Ja, denn es war das gleiche Thema nur mit anderen Mitteln.
                    und so etwas gehört nun mal in den gleichen Post.

                    --
                    Selfcode: ie:{ fl:( br:> va:| ls:& fo:| rl:? n4:& ss:| de:/ js:} mo:) zu:}
                    1. Ok sehe ich ein,
                      das Problem ist meistens nur das vermutlich niemand mehr in so ein altes Thema reinschaut oder?
                      (siehe mein Posting das ich nun hierher verschoben habe)

                      na egal, ich habe ja mal eine Lösung dank deiner Hilfe

                      viele Grüße
                      hawk

  2. Tach.

    Es gibt also immer einen "umgekehrten" Schlüssel

    Diese Schlüssel mit den Werten möchte ich gerne löschen.

    Du möchtest also immer einen Arrayeintrag dieses "Paars" löschen?

    Falls Du sicher weißt, daß zu *jedem* Eintrag einer mit solch umgekehrtem Schlüssel existiert, kannst Du mit usort Dein Array sortieren. Dabei ist nur wichtig, daß die Vergleichsfunktion die beiden Teile eines Paars als "gleich" erkennt. Nach der Sortierung stehen dann immer beide Einträge eines solchen Paars hintereinander im Array. Jeden zweiten löschen. Fertig. Funktioniert aber wie gesagt nur dann, wenn wirklich zu jedem Eintrag ein Gegenstück existiert. Ansonsten verlierst Du ungewollt Einträge!

    Ich frag lieber nicht nach, wie es überhaupt zu dieser komischen Struktur kommt. Vielleicht wäre es aber wesentlich einfacher, an der Stelle, wo sie zusammengebaut wird, solche "Duplikate" auszusortieren anstatt sie ins Array zu stecken.

    --
    Once is a mistake, twice is Jazz.
    1. Hallo Blaubart,
      danke für den Gedankenansatz.

      Ich frag lieber nicht nach, wie es überhaupt zu dieser komischen Struktur kommt. Vielleicht wäre es aber wesentlich einfacher, an der Stelle, wo sie zusammengebaut wird, solche "Duplikate" auszusortieren anstatt sie ins Array zu stecken.

      ich kann es dir gerne erklären wenn du es wissen möchtest. Es handelt sich dabei um eine nahezu alltägliche Windows Anwendung / Funktion. Es ist also nichts selbst erfundenes.

      vielen Dank und viele Grüße
      hawk

    2. Tach.

      Eine Korrektur:

      usort

      Der Hinweis auf usort war natürlich Blödsinn, weil Du in der Callback-Funktion gar nicht auf die Schlüssel zugreifen kannst, nach denen Du eigentlich sortieren willst. Gemeint war uKsort.

      --
      Once is a mistake, twice is Jazz.
      1. Hallo Blaubart,
        herzlichen Dank nochmals für deine Hilfe.

        Der Hinweis auf usort war natürlich Blödsinn, weil Du in der Callback-Funktion gar nicht auf die Schlüssel zugreifen kannst, nach denen Du eigentlich sortieren willst. Gemeint war uKsort.

        Ich glaub das blick ich nicht so recht mir der Vergleichsfunktion.
        Ich habe mal sowas versucht:

        function sortiere($a, $b) {
          $check = explode("#@#",$a);
          $reversekey = $check[1]. "#@#" . $check[0];
          return $reversekey;
        }

        uksort ($main_arr, "sortiere");

        Aber das reicht ja so nicht.
        Und ich frage mich ob da nicht wieder das gleiche passiert wie bei unserem ersten Ansatz, dass nämlich alle Schlüssel durchlaufen und umgedreht werden?

        vielen Dank und viele Grüße
        hawk

        1. Tach.

          Ich glaub das blick ich nicht so recht mir der Vergleichsfunktion.
          Ich habe mal sowas versucht:

          function sortiere($a, $b) {
            $check = explode("#@#",$a);
            $reversekey = $check[1]. "#@#" . $check[0];
            return $reversekey;
          }

          uksort ($main_arr, "sortiere");

          So funktioniert das auch nicht. Die Callback-Funktion soll -1, 0 oder 1 zurückgeben, nicht den Schlüssel.

          Allerdings stelle ich beim Schreiben eines Codebeispiels für Dich gerade fest, daß wir mit meinem Ansatz auch nicht zuverlässig zum Ziel kommen. Da beim Sortieren nicht festgelegt ist, daß jedes Element mit jedem anderen verglichen wird (das ist schließlich kein Bubble Sort), stehen u. U. zum Schluß eben nicht alle Paar zusammen.

          Anstatt also weiter nach möglichen Dreizeilerlösungen zu suchen, sollte man das Aussortieren am besten zu Fuß erledigen: Elementweise durchs Array gehen; den Schlüssel (normal und vertauscht) mit einer Liste schon gesehener Schlüssel vergleichen; falls der Schlüssel noch nicht in dieser Liste existiert, hinzufügen und das Element in ein Ergebnisarray übernehmen; Originalarray wegwerfen.

          --
          Once is a mistake, twice is Jazz.
  3. Hallo,
    Die einhellige Meinung war ja das es besser wäre, schon zu vermeiden das "ähnliche" Werte in die Datenbank reingeschrieben werden. Daher ein neuer Versuch dies schon beim Insert in die DB zu vermeiden.
    Folgendes:
    ich lese mit "preg_match_all" eine Textdatei nach bestimmtem Vorkommen aus.
    Das Ergebnis steht dann in $contents.

    Beispiel Textdatei:

    *Option50 True *Option30 None
    *Option50 True *Option30 EUPHIMPOS
    *Option30 None *Option50 True
    *Option30 EUPHIMPOS *Option50 True
    *Option60 True *Option40 None
    *Option60 XYZ *Option40 WOW
    *Option60 True *Option40 FinEUPHIMPOS
    *Option40 None *Option60 True
    *Option40 WOW  *Option60 XYZ
    *Option40 FinEUPHIMPOS *Option60 True

    Ihr seht also das die Zeilen 3+4 "umgedreht zu Zeile 1+2 sind sowie
    8-10 umgedreht zu Zeilen 5-7

    Bisher hatte ich alles so direkt in die BD Tabelle geschrieben.
    Jetzt versuche ich immer das "umgedrehte" Paar zu ignorieren.

    Hinbekommen habe ich zumindest schon den Gruppenwechsel
    $altegruppe = '';
    $i = 0;
    foreach($contents[0] as $item){
      if($contents[1][$i].$contents[3][$i] == $altegruppe){

    }else  {
     $altegruppe = $contents[1][$i].$contents[3][$i];

    echo "#######Gruppen Wechsel ######## <br>";
      }
      echo "Durchgang $i : Option1:" . $contents[1][$i] . " Wert1: ". $contents[2][$i] . " Option2: ". $contents[3][$i] . " Wert2: ". $contents[4][$i] ."<br>";
      $i++;
    }//foreach

    Bei dieser Echo Ausgabe stehen natürlich immer noch alle Zeilen drin. Allerdings mit dem erkannten Gruppenwechel.

    Ich weiss nun allerdings nicht wie ich weitermachen kann, damit im Beispiel die Zeilen 3-4 und 8-10 nicht ausgegeben bzw. in die DB geschrieben werden.
    Ich mache nun schon einige Zeit herum. Daher wäre ich für jeden Rat sehr dankbar.

    vielen Dank und viele Grüße
    hawk

    1. Yerf!

      Ihr seht also das die Zeilen 3+4 "umgedreht zu Zeile 1+2 sind sowie
      8-10 umgedreht zu Zeilen 5-7

      Bisher hatte ich alles so direkt in die BD Tabelle geschrieben.
      Jetzt versuche ich immer das "umgedrehte" Paar zu ignorieren.

      Hm, das heißt, die Reihenfolge ist nicht von Bedeutung, sondern nur die Zuordnung?

      Dann könnte es weiterhelfen innerhalb der Zeile die Einträge vorher (z.B. alphabetisch) zu sortieren. Damit haben identische Zeilen auch die identische Form und können beim Eintragen in die Datenbank erkannt werden.

      Vielleicht will man das ganze aber auch in 2 Tabellen splitten. Eine die nur einzelne Einträge ("ID", "*Option50", "True") enthält und eine andere die nur die Zuordnungen per IDs herstellt.

      Gruß,

      Harlequin

      --
      <!--[if IE]>This page is best viewed with a webbrowser. Get one today!<![endif]-->