Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]8616[/thread]

Werte in Hash und gleichzeitig doppelte finden

Leser: 1


<< |< 1 2 >| >> 15 Einträge, 2 Seiten
rk-ger
 2007-01-01 23:46
#72839 #72839
User since
2006-08-07
45 Artikel
BenutzerIn
[default_avatar]
Ich habe mich mal wieder festgefahren. Ich muss Werte in ein Hash schieben und dabei doppelte Einträge ignorieren. Im Moment mache ich das in zwei Stufen.

Zuerst die Werte in das Hash
Code: (dl )
1
2
3
for $name(@names2){
push @{$hash{$name}},$row->{$name};
}


und dann das ganze nochmal in ein neues Hash umschaufeln:
Code: (dl )
1
2
3
my %saw;
@saw{@{$hash{$KONSTANTE}}} = ();
my @out = keys %saw;


wobei ich mir nicht sicher bin, was diese Zeile GENAU macht:
Code: (dl )
@saw{@{$hash{$KONSTANTE}}} = ();


Ist das eine Referenz auf ein %hash-Element oder was?

Geht das auch in einem Schritt? Eventuell mit einem zusätzlichen IF 'hash-element-existiert-noch nicht' Block beim Einlesen der Werte in das Hash?
pq
 2007-01-02 00:05
#72840 #72840
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
was willst du denn genau machen? was steht in $KONSTANTE?
was ist dein input, und was willst du als ergebnis haben?
einfach ein array von duplikaten entfernen? perldoc -q duplicate
my %seen;
my @unique = grep { ! $seen{$_}++ } @array;
\n\n

<!--EDIT|pq|1167689269-->
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
rk-ger
 2007-01-02 00:57
#72841 #72841
User since
2006-08-07
45 Artikel
BenutzerIn
[default_avatar]
Der erste Code schreibt das Ergebnis einer SELECT Anfrage in Hashes. Jedes Hash hat danach den Namen der Spalte und enthält alle zurückgegebene Werte der Spalte für weitere Auswertungen.

Der zweite Code entfernt Duplikate, weil ich das Ergebnis bestimmter Spalten wiederum für weitere SELECT Abfragen in der Form
'where tabelle.spalte in (duplikatfreie-liste)'
benötige. In $KONSTANTE stehe jeweils der aktuell benötigte Spaltenname.
renee
 2007-01-02 12:18
#72842 #72842
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Die IN-Liste akzeptiert auch Duplikate!

Das @saw{} ist ein sogenannter Hashslice. Siehe auch:
*) http://slawa.homeip.net/books....08.html
*) http://wiki.preshweb.co.uk/doku.php?id=perl:hashslice
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
bloonix
 2007-01-08 17:59
#72843 #72843
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
[quote=pq,01.01.2007, 23:05]my %seen;
my @unique = grep { ! $seen{$_}++ } @array;
[/quote]
Schönes Beispiel, aber je nach Größe des Arrays ziemlich unschön, da sich
das Ganze verdreifacht. Da würde ich lieber sowas wie

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
use strict;
use warnings;
use Benchmark;

Benchmark::cmpthese(-1,{
'shift' => sub {
my (%seen, $string);
my @array = (0..1000, 0..1000);
$seen{$string}++ while $string = shift @array;
for (keys %seen) {
push @array, $_;
delete $seen{$_};
}
},
'grep' => sub {
my %seen;
my @array = (0..1000, 0..1000);
my @unique = grep { ! $seen{$_}++ } @array;
},
});


bevorzugen, was zudem auch noch um einiges schneller ist:

       Rate  grep shift
grep   431/s    --  -90%
shift 4483/s  941%    --
\n\n

<!--EDIT|opi|1168272145-->
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
pq
 2007-01-08 19:42
#72844 #72844
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
opi: dabei geht die reihenfolge verloren, und das wollte ich vermeiden,
weil nicht ersichtlich war, was der OP genau machen wollte.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
pq
 2007-01-08 19:53
#72845 #72845
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
[quote=opi,08.01.2007, 16:59]Da würde ich lieber sowas wie
Code: (dl )
1
2
      my @array = (0..1000, 0..1000);
     $seen{$string}++ while $string = shift @array;
[/quote]
das ist kaputt. bei 0 hoert deine while-schleife auf.
bitte nochmal.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
pq
 2007-01-08 19:56
#72846 #72846
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
my @a = (0..1000, 0..1000);
Benchmark::timethese($ARGV[0]||-1,{
 "shift" => sub {
    my (%seen, $string);
    my @array = @a;
    $seen{$string}++ while defined ($string = shift @array);
    for (keys %seen) {
       push @array, $_;
delete $seen{$_};
    } return @array;
 },
 "grep"  => sub {
    my %seen;
    my @unique = grep { ! $seen{$_}++ } @a;
 },
});
__END__
     grep:  1 wallclock secs ( 1.04 usr +  0.00 sys =  1.04 CPU) @ 614.42/s (n=639)

    shift:  1 wallclock secs ( 1.03 usr +  0.00 sys =  1.03 CPU) @ 296.12/s (n=305)
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
bloonix
 2007-01-08 20:08
#72847 #72847
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
Hallo pq,

jauh, du hast Recht, ich hab defined() vergessen. Aber soviel
Unterschied ist da nicht...

Rate grep shift
grep 264/s -- -2%
shift 268/s 2% --

Rate shift grep
shift 280/s -- -17%
grep 339/s 21% --

Rate shift grep
shift 277/s -- -6%
grep 295/s 6% --

Rate shift grep
shift 277/s -- -0%
grep 277/s 0% --

Rate shift grep
shift 275/s -- -16%
grep 325/s 18% --

Rate shift grep
shift 277/s -- -5%
grep 291/s 5% --


Da bleibt aber immer noch die unschöne Sache mit der dreifachen
Datengröße.

Danke für deine Aufmerksamkeit. :)
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
pq
 2007-01-08 20:40
#72848 #72848
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
[quote=opi,08.01.2007, 19:08]jauh, du hast Recht, ich hab defined() vergessen. Aber soviel
Unterschied ist da nicht...
[/quote]
bei mir schon.
      Rate shift  grep
shift 300/s    --  -51%
grep  615/s  105%    --
      Rate shift  grep
shift 305/s    --  -52%
grep  633/s  108%    --
      Rate shift  grep
shift 295/s    --  -53%
grep  623/s  112%    --
      Rate shift  grep
shift 309/s    --  -50%
grep  623/s  102%    --

Quote
Da bleibt aber immer noch die unschöne Sache mit der dreifachen
Datengröße.

je nach duplikaten auch weniger, bei deinem bsp. 2 1/2 fach.
und wenn man so viele daten hat, muss man halt überlegen, will
ich lieber 4 stunden lang x MB belegen oder nur 2 stunden x * 2.5.
komm halt drauf an, wieviel speicher verfügbar ist.
jedenfalls ist die grep-lösung deutlich übersichtlicher zu lesen und
dürfte auch erstmal vom speicher her ok sein. wenn man wirklich ein
speicherproblem hat, weil man viele daten hat, kann man es ja
dann anders schreiben.
im idealfall schreibt man gleich in eine datei, dann hat man nur noch
maximal 2 mal so viel speicher.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
<< |< 1 2 >| >> 15 Einträge, 2 Seiten



View all threads created 2007-01-01 23:46.