Cruz: Eintrag in Array einfügen

Hallo!

Wir hatten gestern das Thema wie man einen beliebigen Eintrag aus einem Array entfernen kann, sodaß alle nachfolgenden Einträge nachrücken.

Ist es denn auch möglich einen Eintrag irgendwo in einen Array einzufügen, sodaß die nachfolgenden Einträge abrücken?

Gruß
Cruz

  1. Hallo!

    Wir hatten gestern das Thema wie man einen beliebigen Eintrag aus einem Array entfernen kann, sodaß alle nachfolgenden Einträge nachrücken.

    Ist es denn auch möglich einen Eintrag irgendwo in einen Array einzufügen, sodaß die nachfolgenden Einträge abrücken?

    Gruß
    Cruz

    Hallo Cruz,

    mit der push-Funktion kannst Du z.B. ein Element am Ende eines Arrays anhaengen.

    ----------cut----------

    $x = "Torte";
    @array = ("Pizza, ", "Eis, ", "Kuchen, ", "Perl, ");
    push @array, $x;
    print @array;

    ----------cut----------

    Weitere Informationen zu dieser Funktion erhaeltst Du wenn Du auf der Kommandozeile (z.B. in der DOS-Box) perldoc -f push eingibst oder schau mal bei http://webreview.com/wr/pub/98/12/04/perl/index.html

    Gruesse aus Spanien
       Florian Bender

  2. Hallo Cruz,
    wenn ich einen Eintrag nicht am Ende der Liste einfügen will, mache ich das so:

    @temp = @array;
    @array = @temp[0..$i-1];
    push(@array, $Wert,@temp[$i..$#temp]);

    Der Wert wird dann bei der in $i angegebenen Position eingefügt.
    Kennt jemand vielleicht noch eine elegantere Lösung?

    Gruß
    Andreas

    1. Hallo Cruz,
      wenn ich einen Eintrag nicht am Ende der Liste einfügen will, mache ich das so:

      @temp = @array;
      @array = @temp[0..$i-1];
      push(@array, $Wert,@temp[$i..$#temp]);

      Der Wert wird dann bei der in $i angegebenen Position eingefügt.
      Kennt jemand vielleicht noch eine elegantere Lösung?

      Gruß
      Andreas

      Hallo Andreas,

      klasse diese Lösung, ich habs grad tetestet werriwell!
      Was meinst Du mit eleganter? kürzer? wohl kaum :-)

      Viele Grüße, Rolf

    2. Hallo Andreas!

      @temp = @array;
      @array = @temp[0..$i-1];
      push(@array, $Wert,@temp[$i..$#temp]);

      Ich will Dich ja nicht aergern... aber bei dieser Methode ist offensichtlich, dass Unmengen von Daten im Speicher hin- und herkopiert werden. Es ist immer besser, eine builtin-Funktion zu nutzen, wenn eine vorhanden ist. (Schon klar, Du hast nicht gewusst, dass es splice gibt.) Ich hab einfach mal schnell einen kleinen Performancetest geschrieben - der Quelltext steht unten - und hier ist das Ergebnis:

      Testing the splice method... The splice method took 1 seconds.
          Testing the push method... The push method took 500 seconds.

      Alles klar? ;-)
      Testmaschine war ein 133 MHz Cyrix Prozessor (Cyrix P166+) mit ausreichend L1- und L2-Cache. OS ist WinNT4 SP3.

      Im Anschluss noch der Source-Code.

      Calocybe

      ======================================

      #!/path/to/perl

      $NUMBER_OF_INITIAL_ELEMENTS = 20000;
      $NUMBER_OF_INSERTED_ELEMENTS = 1000;
      $INSERT_POSITION = 10000;

      @array = ();

      sub reset_array {
          my $i;

      @array = ();
          for ($i=0; $i<$NUMBER_OF_INITIAL_ELEMENTS; $i++) {
              push @array, "array element ".$i;
          }
      }

      sub insert_via_splice {
          my $position = shift;
          my $new_element = shift;

      splice @array, $position, 0, $new_element;
      }

      sub insert_via_push {
          my @temp;
          my $position = shift;
          my $new_element = shift;

      @temp = @array;
          @array = @temp[0..$position-1];
          push(@array, $new_element, @temp[$position..$#temp]);
      }

      sub main {
          my ($starttime, $splice_duration, $push_duration);
          my $i;

      #
          # test the splice method
          #
          print "Testing the splice method... ";
          reset_array();
          $starttime = time();

      for ($i=0; $i<$NUMBER_OF_INSERTED_ELEMENTS; $i++) {
              insert_via_splice($INSERT_POSITION, "subsequently inserted element ".$i);
          }

      $splice_duration = time() - $starttime;
          print "The splice method took $splice_duration seconds.\n";

      #
          # test the push method
          #
          print "Testing the push method... ";
          reset_array();
          $starttime = time();

      for ($i=0; $i<$NUMBER_OF_INSERTED_ELEMENTS; $i++) {
              insert_via_push($INSERT_POSITION, "subsequently inserted element ".$i);
          }

      $push_duration = time() - $starttime;
          print "The push method took $push_duration seconds.\n";
      }

      main();

      ======================================

      1. Hallo Calocybe!

        Es ist immer besser, eine builtin-Funktion zu nutzen, wenn eine vorhanden ist.

        Danke, genau das hatte ich gesucht, aber nicht gefunden.

        Gruß
        Andreas

  3. Ist es denn auch möglich einen Eintrag irgendwo in einen Array einzufügen, sodaß die nachfolgenden Einträge abrücken?

    Du scheinst Perl ein wenig "vergewaltigen" zu wollen.
    Für Deine Anwendung mit Einfügen und Löschen halte ich Arrays nicht für den passenden Datentyp. Es würde wahrscheinlich alles einfacher und vor allem performanter werden, wenn Du auf Hashes umsteigen würdest.
    Die sequentielle Verarbeitung eines Arrays bekommst Du dort mit "foreach"; einen direkt indizierten Zugriff scheinst Du ja nicht zu brauchen, weil sich die Indizes durch das ständige Einfügen und Löschen ohnehin dauernd ändern.

  4. Hi!

    Wir hatten gestern das Thema wie man einen beliebigen Eintrag aus einem Array entfernen kann, sodaß alle nachfolgenden Einträge nachrücken.

    Richtig, und genau da steht schon die Antwort auf Deine heutige Frage. Setze bei splice die Lange auf 0 und Du hast was Du willst.

    Calocybe