Jean-Luc: Zwei Arrays "elegant" vergleichen

Hallo Perl Profis,

ich möchte den Inhalt zweier Arrays vergleichen, und
will die Elemente ausgegeben bekommen, die unterschiedlich
sind (sowol, vom einen als auch vom anderen).

Nun gibt es hierfür mehrere Möglichkeiten:

1. Umwandeln in einen Hash und Abfrage mit exists
2. Foreach oder ähnliches und Vergleich der einzelnen Elemente
.
.
.

Gibt es da nicht was eleganteres und oder schnelleres ???

Vielen Dank
Gruß
Jean-Luc

  1. Hallo,

    ich möchte den Inhalt zweier Arrays vergleichen, und
    will die Elemente ausgegeben bekommen, die unterschiedlich
    sind (sowol, vom einen als auch vom anderen).

    for (my $i=0;$i<=$#array_eins;$i++)
    {
        next if($array_eins[$i] eq $array_zwei[$i]);
        print "$array_eins[$i]:$array_eins[$i] - $array_zwei[$i]:$array_zwei[$i]\n";
    }

    Gruß Markus

    1. Hallo,

      ich möchte den Inhalt zweier Arrays vergleichen, und
      will die Elemente ausgegeben bekommen, die unterschiedlich
      sind (sowol, vom einen als auch vom anderen).

      for (my $i=0;$i<=$#array_eins;$i++)
      {
          next if($array_eins[$i] eq $array_zwei[$i]);
          print "$array_eins[$i]:$array_eins[$i] - $array_zwei[$i]:$array_zwei[$i]\n";
      }

      Gruß Markus

      Hi Markus,

      Danke für Deinen Lösungsvorschlag, nur was mache ich,
      wenn die Reihenfolge nicht gleich ist, bzw. wenn ein
      Array ein Element mehr hat, als der Andere (und
      das evtl. gleich zu Beginn ) ???

      Gruß
      Jean-Luc

      P.S. Vielleicht war auch meine Fragestellung nicht
      präzise genug

      1. Hallo,

        nur was mache ich,
        wenn die Reihenfolge nicht gleich ist, bzw. wenn ein
        Array ein Element mehr hat, als der Andere (und
        das evtl. gleich zu Beginn ) ???

        Also dann dürfte das ungleich schwieriger werden. Du müsstest dann jeden Eintrag des einen Arrays, mit _allen_ Einträgen des Anderen vergleichen. Also so:

        foreach my $eintrag1(@array_eins)
        {
          foreach my $eintrag2(@array_zwei)
          {
            if($eintrag1 ne $eintrag2) blablabla;
          }
        }

        HTH Markus

        1. Hallo,

          nur was mache ich,
          wenn die Reihenfolge nicht gleich ist, bzw. wenn ein
          Array ein Element mehr hat, als der Andere (und
          das evtl. gleich zu Beginn ) ???

          Also dann dürfte das ungleich schwieriger werden. Du müsstest dann jeden Eintrag des einen Arrays, mit _allen_ Einträgen des Anderen vergleichen. Also so:

          foreach my $eintrag1(@array_eins)
          {
            foreach my $eintrag2(@array_zwei)
            {
              if($eintrag1 ne $eintrag2) blablabla;
            }
          }

          HTH Markus

          Hi,

          genau, das war meine Frage bzw. Problem.
          Gibt es da nicht was "eleganteres" ???????????

          1. Moin!

            genau, das war meine Frage bzw. Problem.
            Gibt es da nicht was "eleganteres" ???????????

            Du hättest gerne eine Funktion, die dir automatisch alle unterschiedlichen Arrayelemente auswirft, ohne viel Nachdenken, wie der Vergleich läuft?

            Selber machen ist da die beste Lösung. Und "eleganter" als alle Elemente mit allen Elementen zu vergleichen, gehts sicherlich nicht, weil das den Erfolg nicht garantieren würde.

            Du mußt für jedes Element eines Arrays feststellen, ob es im anderen Array enthalten ist. Also einmal für jedes Element das gesamte andere Array durchlaufen. Und für die Elemente des anderen Arrays gilt das gleiche.

            Die Sache wird vielleicht etwas einfacher und schneller, wenn du die Arrays vorher sortierst und einen Index anlegst, oder gar in einem binären Baum ablegst, weil du dann für die Such-Operation weniger Zeit brauchst.

            Die spannende Frage ist: Sind deine Arrays so groß, daß der Sortieraufwand den Zeitgewinn rechtfertigt? Schließlich kostet das auch Zeit.

            - Sven Rautenberg

            1. Hi Sven,

              Du hättest gerne eine Funktion, die dir automatisch alle unterschiedlichen Arrayelemente auswirft, ohne viel Nachdenken, wie der Vergleich läuft?

              Genau. Es gibt doch für Perl eigentlich alles.
              Wieso nicht auch sowas. Das ist doch jetzt wirklich nicht
              eine so aussergewöhnliche Aufgabe ?!

              Selber machen ist da die beste Lösung. Und "eleganter" als alle Elemente mit allen Elementen zu vergleichen, gehts sicherlich nicht, weil das den Erfolg nicht garantieren würde.

              Hm, ich glaube, die Verwendung von Hashes ist da doch
              noch etwas eleganter, und evtl. auch schneller, da ich
              ja mit "delete" die bereits gefundenen Elemente entfernen
              kann, und dadurch die Menge stets kleiner wird ?!

              Die Sache wird vielleicht etwas einfacher und schneller, wenn du die Arrays vorher sortierst und einen Index anlegst, oder gar in einem binären Baum ablegst, weil du dann für die Such-Operation weniger Zeit brauchst.

              Binäre Bäume !!!
              Kanonen auf Spatzen ?! ;-)
              Nö, kenn ich nicht, mag ich nicht :-)

              Die spannende Frage ist: Sind deine Arrays so groß, daß der Sortieraufwand den Zeitgewinn rechtfertigt? Schließlich kostet das auch Zeit.

              Jein, nur das Problem ist bei mir immer wieder mal aufgetaucht,
              und ich hätte einfach mal gewußt wie das die "Profis" so machen.
              Ich arbeite zwar jetzt auch seit über einem Jahr mit Perl,
              doch habe ich immer noch keine (in meinen Augen) elegante
              Lösung gefunden.

              Vielen Dank für Eure Zeit
              Gruß
              Jean-Luc

              1. Moin!

                Die spannende Frage ist: Sind deine Arrays so groß, daß der Sortieraufwand den Zeitgewinn rechtfertigt? Schließlich kostet das auch Zeit.
                Jein, nur das Problem ist bei mir immer wieder mal aufgetaucht,
                und ich hätte einfach mal gewußt wie das die "Profis" so machen.
                Ich arbeite zwar jetzt auch seit über einem Jahr mit Perl,
                doch habe ich immer noch keine (in meinen Augen) elegante
                Lösung gefunden.

                Was auch funktionieren könnte: Gib jedem Arrayelement ein Kennzeichen mit, aus welchem Array es ursprünglich kommt, schiebe alle Elemente aus den Arrays in ein neues Array, sortiere, und wenn dann Elemente nicht doppelt hintereinander auftreten, dann gab es sie wohl nur einmal. :)

                - Sven Rautenberg

  2. hi!

    ich möchte den Inhalt zweier Arrays vergleichen, und
    will die Elemente ausgegeben bekommen, die unterschiedlich
    sind (sowol, vom einen als auch vom anderen).

    Die Vehemenz, mit der hier die Perl-Dokumentation ignoriert wird, ist
    erstaunlich... ;))

    Aus der perlfaq[1]:

    === cut ===
    How do I compute the difference of two arrays? How do I compute the
    intersection of two arrays?

    Use a hash. Here's code to do both and more. It assumes that each
    element is unique in a given array:

    @union = @intersection = @difference = ();
        %count = ();
        foreach $element (@array1, @array2) { $count{$element}++ }
        foreach $element (keys %count) {
            push @union, $element;
            push @{ $count{$element} > 1 ? @intersection : @difference }, $element;
        }

    Note that this is the symmetric difference, that is, all elements in
    either A or in B but not in both. Think of it as an xor operation.
    === cut ===

    Mit der obigen Routine kann man noch nicht feststellen, in welchem
    Array ein bestimmtes Element fehlt. Dafür hat der Algorithmus
    lineare Effizienz und keine quadratische wie der, den Sven vorge-
    schlagen hat... :)

    bye, Frank!

    [1] http://www.perldoc.com/perl5.6.1/pod/perlfaq4.html#How-do-I-compute-the-difference-of-two-arrays---How-do-I-compute-the-intersection-of-two-arrays-