http://www.perlmonks.org?node_id=379048


in reply to Re: scanning hash
in thread scanning hash

That works, is brief, and hip. It is possibly not however the most efficient solution as it fails to utilize an iterative, fail fast approach and requires generating and manipulating un-used anon data stuctures. Given the task we can look at less of the hash if we simply fail fast as soon as we detect a non matching value. Depending on the context this may or may not matter. Still a very cool solution though. Wish I had of thought of it. What the hell, I will next time :-)

print ident( { foo=>1, bar=>1, baz=>1 } ); sub ident { my $value = (values %{$_[0]})[0]; for (values %{$_[0]} ) { return 0 unless $value eq $_; } return 1; }

cheers

tachyon

Replies are listed 'Best First'.
Re^3: scanning hash
by Aristotle (Chancellor) on Aug 01, 2004 at 14:56 UTC

    You'll have to extend that a bit so it properly deals with undef vs empty string.

    sub ident { my $value = ( values %{ $_[0] } )[0]; for ( values %{ $_[0] } ) { no warnings 'uninitialized'; return 0 unless !( defined $value xor defined $_ ) and ( $valu +e eq $_ ); } return 1; }

    It would be better if I could think of a way to skip the $value eq $_ test when both variables are undefined, and still have the entire expression be true, but I can't see a way to do that without an extra test for definedness on one of the values.


    Update after bageler's reply: this was wrong:

    return 0 unless ( defined $value xor defined $_ ) and ( $value eq $_ ) +;

    The condition will only ever be true when comparing an undef with an empty string, but in no other case, because the left expression is only true if the operands are unequal, ie if only one of them is defined. In that case, the right expression can only also be true if the defined value is an empty string.

    Makeshifts last the longest.

      need to change that slightly so it will return true if all the keys are undef:
      return 0 unless defined $_ ? $_ eq $value : defined $value ? 0 : 1

        No, I don't.

        $ perl -le'print undef eq undef' 1

        Update: oh, I see what made you think that. I had to NOT my XOR condition. I forgot that XOR produces false rather than true if both operands are equal.

        Makeshifts last the longest.