[Israel.pm] Case Study: Splitting a Hash into Two

Shlomi Fish shlomif at iglu.org.il
Thu Jul 15 23:51:21 PDT 2004


On Thursday 15 July 2004 22:15, Yuval Yaari wrote:
> Funny, that's exactly what I had in mind when reading the original post.
> I was wondering if someone isn't as lazy as I am and actually benchmarked
> it???
>

Well, I did not benchmark it, but I think that while Migo's code is adequate 
in which there are only two subset hashes, it scales poorly if there are 
more. O(N*M) instead of O(N). There is no need to iterate over the hash M 
times. 

> I just wanted to say that this kind of programming gives Perl a bad name
> [in my eyes, at least].
>
> And even though a map {} grep chain is ugly/hack-ish -- perldoc -f on each
> of those would give you the right picture.

Why is a map+grep chain ugly and hack-ish?

> The only things I can perldoc out of your code are "while" and "each" and
> they wouldn't help a user get a good understanding at what your code does.
>

Really? I always thought that while and each are a common paradigm of 
iterating over a hash. And my generalized solution, is quite easy to 
understand.

> I would add that I might be biased because `map` must be my all-time
> favorite Perl built-in function.
>

I also like map.

Regards,

	Shlomi Fish

>   --Yuval
>
> Mikhael Goikhman said:
> > On 14 Jul 2004 21:48:30 +0300, Shlomi Fish wrote:
> >> Today I hanged around FreeNode's #perl channel. Someon asked for a way
> >> to  generate two hashes out of one, with one containing only the keys
> >> that start  with underscore, and the other the rest. After some
> >> thinking and planning I  came out with this code:
> >>
> >> <<<
> >> sub split_hash
> >> {
> >>     my $h = shift;
> >>     # us is underscore not the United States.
> >>     my (%us_hash, %non_us_hash);
> >>     while (my ($k, $v) = each(%$h))
> >>     {
> >>         (($k =~ /^_/o) ? \%us_hash : \%non_us_hash)->{$k} = $v;
> >>     }
> >>     return (\%us_hash, \%non_us_hash);
> >> }
> >>
> >>
> >> (tested, BTW).
> >
> > I think I would do it this way (at least if the run time is cheap):
> >
> > 	my %under_hash = map { $_ => $hash{$_} } grep  /^_/, keys %hash;
> > 	my %other_hash = map { $_ => $hash{$_} } grep !/^_/, keys %hash;
> >
> > Regards,
> > Mikhael.
> >
> > --
> > perl -e 'print+chr(64+hex)for+split//,d9b815c07f9b8d1e'
> > _______________________________________________
> > Perl mailing list
> > Perl at perl.org.il
> > http://perl.org.il/mailman/listinfo/perl
>
> _______________________________________________
> Perl mailing list
> Perl at perl.org.il
> http://perl.org.il/mailman/listinfo/perl

-- 

---------------------------------------------------------------------
Shlomi Fish      shlomif at iglu.org.il
Homepage:        http://shlomif.il.eu.org/

Knuth is not God! It took him two days to build the Roman Empire.



More information about the Perl mailing list