User since
2005-01-13
782
Artikel
BenutzerIn
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my @ar1 = ( {'name' => 1, 'id' => 1},
{'name' => 2, 'id' => 2},
{'name' => 3, 'id' => 3},
{'name' => 4, 'id' => 4},
{'name' => 5, 'id' => 5}
);
my @ar2 = qw(4 5 6 7 8);
foreach(@ar1) {
if( grep (/$_->{'name'}/, @ar2) ) { # Zeile 18
print $_->{'name'}."drin\n";
}
}
also eigentlich ganz einfach. ich möchte einfach nur schauen, ob ein name aus meinem AoH in dem array @ar2 vorkommt.
ich bekomme aber folgende fehlermeldung:
QuoteCan't use string ("4") as a HASH ref while "strict refs" in use at test1.pl line 18.
Attempt to free unreferenced scalar: SV 0x22529c, Perl interpreter: 0x2242bc.
was mache ich da falsch? wenn ich $_->{'name'} ausprinte krieg ich auch jedes element im schleifendurchlauf auf die konsole geschrieben, aber im grep geht das nicht?\n\n
<!--EDIT|vayu|1150443962-->
User since
2005-01-13
782
Artikel
BenutzerIn
bin ich da evtl auf nen $_ "trick" reingefallen? setzt grep das irgendwie neu? :)
hab jetzt mal ein foreach my $var eingesetzt und damit bekomme ich keine fehlermeldung.\n\n
<!--EDIT|vayu|1150443933-->
User since
2003-08-04
2536
Artikel
ModeratorIn
japp, grep setzt $_ für das jeweils aktive element.
User since
2005-01-13
782
Artikel
BenutzerIn
ok dann wird mir einiges klarer -.-
danke
User since
2003-08-04
12208
Artikel
Admin1
grep ..., @array setzt in jedem durchlauf die spezielle variable
$_
als alias für das gerade bearbeitete element. also im prinzip genauso
wie
for.
perl kann nicht ahnen, dass du hier das äußere $_ meinst. zudem ist deine
logik etwas komisch. wenn du mit dem $_ das äußere meinst, würdest du
foreach my $ar1 (@ar1) {
if( grep ($ar1->{'name'}, @ar2) ) { # Zeile 18
print $ar1->{'name'}."drin\n";
}
}
schreiben müssen.
das grep ist völlig sinnlos, du prüfst einfach nur 5 mal (@ar2), ob
$ar1->{name} einen wahren wert enthält.
wahrscheinlich willst du
grep { $ar1->{name} eq $_ } @ar2\n\n
<!--EDIT|pq|1150444642-->
User since
2005-01-13
782
Artikel
BenutzerIn
ich hatte meinen oberen post noch verbessert, hatte nen tippfehler in meinem testskript -.-
ich wollte das
foreach my $ar1 (@ar1) {
if( grep (/$ar1->{'name'}/, @ar2) ) { # Zeile 18
print $ar1->{'name'}."drin\n";
}
}
die / / fehlten im grep
und das funktioniert ja auch, weil ein m// oder auch // ja mit $_ vergleichen.
aber wie heisst es so schön ;) durch Fehler lernt man und ich hab wieder mal was gelernt ^^\n\n
<!--EDIT|vayu|1150446999-->
User since
2003-08-04
2145
Artikel
ModeratorIn + EditorIn
Wenn dein @ar2 eine 10 enthielte, wäre das Ergebnis auch "drin".
Vielleicht wäre das von pq vorgeschlagene "eq" doch besser?
User since
2003-08-04
12208
Artikel
Admin1
[quote=vayu,16.06.2006, 10:34]die / / fehlten im grep
und das funktioniert ja auch, weil ein m// oder auch // ja mit $_ vergleichen.
[/quote]
wenn man zwei strings $x und $y auf gleichheit überprüfen will,
benutzt man eigentlich nicht
$x =~ /$y/, sondern
$x eq $y.
wieso sollte man das in einem grep anders machen, zumal die
lösung mit regex auch noch falsch ist (siehe dubus antwort)?\n\n
<!--EDIT|pq|1150450017-->
User since
2005-01-13
782
Artikel
BenutzerIn
ok stimmt.
ich gebe mich geschlagen :)
aber wenn ich nun ein
/^$y$/ machen würde, würds wieder passen ^^ hatte wieder n regexp fehler drin ... sorry
User since
2003-08-04
2145
Artikel
ModeratorIn + EditorIn
[quote=vayu,16.06.2006, 11:53]aber wenn ich nun ein
/^$y$/ machen würde, würds wieder passen[/quote]
Und wenn dein $y ein Zeichen enthält, das in einer Regex eine besondere Bedeutung hat (wie ., *, +, ?, [, ], (, ), ^, $), dann passt es wieder nicht mehr.
Ja, das kann man auch wieder beheben, mit quotemeta() oder \Q...\E. Aber wie kompliziert soll es denn noch werden, nur damit nicht einfach ein 'eq' da steht? ;)