I need help with this regex. It looks the keys of fdat are searched for
"$prefix" and fdat hash is deleted. I have no idea what the map is
trying to do. Thanks for your help.
debug my %indices = map { (/^\Q$prefix.\E(.+)/), $_ } grep { delete
$fdat{$_} } grep /^\Q$prefix.\E/, keys %fdat;
|
|
0
|
|
|
|
Reply
|
soup_or_power (214)
|
4/7/2005 5:16:13 PM |
|
X-Ftn-To: soup_or_power@yahoo.com
soup_or_power@yahoo.com wrote:
>I need help with this regex. It looks the keys of fdat are searched for
>"$prefix" and fdat hash is deleted. I have no idea what the map is
>trying to do. Thanks for your help.
map is producing hash pairs, where keys are striped %fdat keys (and values
are unmodified %fdat keys).
> debug my %indices = map { (/^\Q$prefix.\E(.+)/), $_ } grep { delete
>$fdat{$_} } grep /^\Q$prefix.\E/, keys %fdat;
#untested
my %indices =
map { /^\Q$prefix.\E(.+)/, $_ }
grep /^\Q$prefix./ && delete $fdat{$_},
keys %fdat;
This is somehow shorter but..
my %indices =
map {
my $k = $_;
s!^\Q$prefix.!! && delete $fdat{$k} ? ($_ => $k) : ();
}
keys %fdat;
... here we are using only one regex so it should be little faster if speed
counts.
--
Matija
|
|
0
|
|
|
|
Reply
|
Matija
|
4/7/2005 6:04:03 PM
|
|
On 7 Apr 2005 soup_or_power@yahoo.com wrote:
> I need help with this regex. It looks the keys of fdat are searched for
> "$prefix" and fdat hash is deleted. I have no idea what the map is
> trying to do. Thanks for your help.
>
> debug my %indices = map { (/^\Q$prefix.\E(.+)/), $_ } grep { delete
> $fdat{$_} } grep /^\Q$prefix.\E/, keys %fdat;
That's likely to be wrong as 'map' may return an odd number of elements
to %indices. Perhaps the intent was something like this?
my %indices =
map { /^\Q$prefix.\E(.+)/ ? $1 : '' , $_ }
grep { delete $fdat{$_} }
grep /^\Q$prefix.\E/,
keys %fdat;
That's still too obfuscated for my tastes. I'd prefer:
my %indices;
my @keys_to_remove_from_fdat;
for my $k (keys %fdat)
{
if ($k =~ /^\Q$prefix.\E(.*)/)
{
$indices{$1} = $k;
push @keys_to_remove_from_fdat, $k;
}
}
delete @fdat{@keys_to_remove_from_fdat};
--
Hope this helps,
Steven
|
|
0
|
|
|
|
Reply
|
Steven
|
4/7/2005 6:42:17 PM
|
|
soup_or_power@yahoo.com wrote:
> I need help with this regex. It looks the keys of fdat are searched for
> "$prefix" and fdat hash is deleted. I have no idea what the map is
> trying to do. Thanks for your help.
>
> debug my %indices = map { (/^\Q$prefix.\E(.+)/), $_ } grep { delete
> $fdat{$_} } grep /^\Q$prefix.\E/, keys %fdat;
Well, let's have a look:
john@perl john $ perl -le'use Data::Dumper;
my %x = qw/ abc.123 2 abc.234 3 abc.345 4 abc.456 5 abc.567 6 xyz.123 7
xyz.234 8 xyz.345 9 /;
print Dumper \%x;
my $prefix = q/abc/;
my %y = map { (/^\Q$prefix.\E(.+)/), $_ } grep { delete $x{$_} } grep
/^\Q$prefix.\E/, keys %x;
print Dumper \%x, \%y;
'
$VAR1 = {
'xyz.345' => '9',
'abc.123' => '2',
'abc.456' => '5',
'xyz.234' => '8',
'abc.345' => '4',
'abc.567' => '6',
'xyz.123' => '7',
'abc.234' => '3'
};
$VAR1 = {
'xyz.345' => '9',
'xyz.234' => '8',
'xyz.123' => '7'
};
$VAR2 = {
'345' => 'abc.345',
'456' => 'abc.456',
'123' => 'abc.123',
'567' => 'abc.567',
'234' => 'abc.234'
};
John
--
use Perl;
program
fulfillment
|
|
0
|
|
|
|
Reply
|
John
|
4/7/2005 7:18:29 PM
|
|
* Steven Kuo schrieb:
>
> That's still too obfuscated for my tastes. I'd prefer:
>
> my %indices;
> my @keys_to_remove_from_fdat;
> for my $k (keys %fdat) {
> if ($k =~ /^\Q$prefix.\E(.*)/) {
> $indices{$1} = $k;
> push @keys_to_remove_from_fdat, $k;
> }
> }
> delete @fdat{@keys_to_remove_from_fdat};
It seems that the values of the hash %indices are the same as the
elements of the array @keys_to_remove_from_fdat. You could write
my %indices;
for ( keys %fdat ) {
$indices{$1} = $_ if /^\Q$prefix.\E(.*)/;
}
delete @fdat{ values %indices };
regards,
fabian
|
|
0
|
|
|
|
Reply
|
Fabian
|
4/7/2005 8:24:43 PM
|
|
Steven Kuo <skuo@mtwhitney.nsc.com> wrote in comp.lang.perl.misc:
> On 7 Apr 2005 soup_or_power@yahoo.com wrote:
>
> > I need help with this regex. It looks the keys of fdat are searched for
> > "$prefix" and fdat hash is deleted. I have no idea what the map is
> > trying to do. Thanks for your help.
> >
> > debug my %indices = map { (/^\Q$prefix.\E(.+)/), $_ } grep { delete
> > $fdat{$_} } grep /^\Q$prefix.\E/, keys %fdat;
>
>
>
> That's likely to be wrong as 'map' may return an odd number of elements
How? The first grep (chronologically, so textually the last one) makes
sure that /^\Q$prefix.\E/ will always match, so the map block will
always return exactly two elements.
I agree that the operation could be better written.
Anno
|
|
0
|
|
|
|
Reply
|
anno4000
|
4/8/2005 9:18:09 AM
|
|
On Fri, 8 Apr 2005, Anno Siegel wrote:
> Steven Kuo <skuo@mtwhitney.nsc.com> wrote in comp.lang.perl.misc:
>> On 7 Apr 2005 soup_or_power@yahoo.com wrote:
>>
>>> I need help with this regex. It looks the keys of fdat are searched for
>>> "$prefix" and fdat hash is deleted. I have no idea what the map is
>>> trying to do. Thanks for your help.
>>>
>>> debug my %indices = map { (/^\Q$prefix.\E(.+)/), $_ } grep { delete
>>> $fdat{$_} } grep /^\Q$prefix.\E/, keys %fdat;
>>
>>
>>
>> That's likely to be wrong as 'map' may return an odd number of elements
>
> How? The first grep (chronologically, so textually the last one) makes
> sure that /^\Q$prefix.\E/ will always match, so the map block will
> always return exactly two elements.
>
> I agree that the operation could be better written.
>
The problem is subtle. However there is a string that will
pass through the grep "filter" pattern but fail to match the
map "key generation" pattern. In particular, this string:
$prefix . '.';
The failed match in list context does not return a empty string
but instead omits an element.
One can see this more clearly if we return the output to an
array:
use Data::Dumper;
my $prefix = 'foo';
my @count_items =
map { (/^\Q$prefix.\E(.+)/), $_ }
grep /^\Q$prefix.\E/,
(
$prefix . '.',
$prefix . '.something else'
);
print Dumper \@count_items;
$VAR1 = [
'foo.',
'something else',
'foo.something else'
];
There are an odd number of elements! Worse is that perl will,
without warnings enabled, tacitly accept this and construct a hash
with corrupted data:
my %bad_results =
map { (/^\Q$prefix.\E(.+)/), $_ }
grep /^\Q$prefix.\E/,
(
$prefix . '.',
$prefix . '.something else'
);
print Dumper \%bad_results;
$VAR1 = {
'foo.something else' => undef,
'foo.' => 'something else'
};
I'm not the OP, who may be willing to assert that "my data will never
look like that".
The alternative code I proposed, however, does not return an odd
number of elements, regardless of the form of input data.
--
Regards,
Steven
|
|
0
|
|
|
|
Reply
|
Steven
|
4/8/2005 5:07:11 PM
|
|
Steven Kuo wrote:
> On Fri, 8 Apr 2005, Anno Siegel wrote:
>
>> Steven Kuo <skuo@mtwhitney.nsc.com> wrote in comp.lang.perl.misc:
>>
>>> On 7 Apr 2005 soup_or_power@yahoo.com wrote:
>>>
>>>> I need help with this regex. It looks the keys of fdat are searched for
>>>> "$prefix" and fdat hash is deleted. I have no idea what the map is
>>>> trying to do. Thanks for your help.
>>>>
>>>> debug my %indices = map { (/^\Q$prefix.\E(.+)/), $_ } grep { delete
>>>> $fdat{$_} } grep /^\Q$prefix.\E/, keys %fdat;
>>>
>>> That's likely to be wrong as 'map' may return an odd number of elements
>>
>> How? The first grep (chronologically, so textually the last one) makes
>> sure that /^\Q$prefix.\E/ will always match, so the map block will
>> always return exactly two elements.
>>
>> I agree that the operation could be better written.
>
> The problem is subtle. However there is a string that will pass through
> the grep "filter" pattern but fail to match the map "key generation"
> pattern. In particular, this string:
>
> $prefix . '.';
>
> The failed match in list context does not return a empty string
> but instead omits an element.
That can be "fixed" by adding one character to the original:
my %indices = map { (/^\Q$prefix.\E(.+)/), $_ } grep { delete $fdat{$_} } grep
/^\Q$prefix.\E./, keys %fdat;
John
--
use Perl;
program
fulfillment
|
|
0
|
|
|
|
Reply
|
John
|
4/8/2005 10:13:15 PM
|
|
|
7 Replies
68 Views
(page loaded in 0.094 seconds)
|