Skip to content

Commit

Permalink
change keys() and add values()
Browse files Browse the repository at this point in the history
  • Loading branch information
Hans Dieter Pearcey committed Jan 30, 2010
1 parent 46356a5 commit 9db6f50
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 10 deletions.
39 changes: 36 additions & 3 deletions README
Expand Up @@ -15,8 +15,8 @@ SYNOPSIS
my $foo = $hash->get('foo'); # 'b' (always, regardless of context)
my @foo = $hash->get_all('foo'); # ('a', 'b')

keys %$hash; # ('foo', 'bar') not guaranteed to be ordered
$hash->keys; # ('foo', 'bar') guaranteed to be ordered
keys %$hash; # ('foo', 'bar') not guaranteed to be ordered
$hash->keys; # ('foo', 'foo', 'bar') guaranteed to be ordered

DESCRIPTION
Hash::MultiValue is an object (and a plain hash reference) that may
Expand Down Expand Up @@ -109,7 +109,15 @@ METHODS
keys
@keys = $hash->keys;

Returns a list of keys, in an ordered way.
Returns a list of all keys, including duplicates (see the example in
the "SYNOPSIS").

If you want only unique keys, use "keys %$hash", as normal.

values
@values = $hash->values;

Returns a list of all values, in the same order as "$hash->keys".

add
$hash->add($key, $value [, $value ... ]);
Expand All @@ -133,6 +141,31 @@ METHODS
Gets pairs of keys and values. This should be exactly the same pairs
which are given to "new" method unless you updated the data.

each
$hash->each($code);

# e.g.
$hash->each(sub { print "$_[0] = $_[1]\n" });

Calls $code once for each "($key, $value)" pair. This is a more
convenient alternative to calling "flatten" and then iterating over
it two items at a time.

Inside $code, $_ contains the current iteration through the loop,
starting at 0. For example:

$hash = Hash::MultiValue->new(a => 1, b => 2, c => 3, a => 4);

$hash->each(sub { print "$_: $_[0] = $_[1]\n" });
# 0: a = 1
# 1: b = 2
# 2: c = 3
# 3: a = 4

Be careful not to change @_ inside your coderef! It will update the
tracking object but not the plain hash. In the future, this
limitation may be removed.

clone
$new = $hash->clone;

Expand Down
25 changes: 19 additions & 6 deletions lib/Hash/MultiValue.pm
Expand Up @@ -127,8 +127,12 @@ sub clone {

sub keys {
my $self = shift;
my %seen;
grep { !$seen{$_}++ } @{$keys{refaddr $self}};
return @{$keys{refaddr $self}};
}

sub values {
my $self = shift;
return @{$values{refaddr $self}};
}

sub flatten {
Expand Down Expand Up @@ -164,7 +168,7 @@ sub as_hashref_mixed {

my %hash;
push @{$hash{$k->[$_]}}, $v->[$_] for 0 .. $#$k;
for (values %hash) {
for (CORE::values %hash) {
$_ = $_->[0] if 1 == @$_;
}

Expand Down Expand Up @@ -213,8 +217,8 @@ Hash::MultiValue - Store multiple values per key
my $foo = $hash->get('foo'); # 'b' (always, regardless of context)
my @foo = $hash->get_all('foo'); # ('a', 'b')
keys %$hash; # ('foo', 'bar') not guaranteed to be ordered
$hash->keys; # ('foo', 'bar') guaranteed to be ordered
keys %$hash; # ('foo', 'bar') not guaranteed to be ordered
$hash->keys; # ('foo', 'foo', 'bar') guaranteed to be ordered
=head1 DESCRIPTION
Expand Down Expand Up @@ -320,7 +324,16 @@ attached, the result will be an empty list.
@keys = $hash->keys;
Returns a list of keys, in an ordered way.
Returns a list of all keys, including duplicates (see the example in the
L</SYNOPSIS>).
If you want only unique keys, use C<< keys %$hash >>, as normal.
=item values
@values = $hash->values;
Returns a list of all values, in the same order as C<< $hash->keys >>.
=item add
Expand Down
3 changes: 3 additions & 0 deletions t/hash.t
Expand Up @@ -58,6 +58,9 @@ my $hash = Hash::MultiValue->new(
[ foo => 'b', foo => 'c', bar => 'bba', baz => 34 ];
is_deeply $hash,
{ foo => 'b', bar => "baz", baz => 33 };

is_deeply [ $hash->keys ], [ qw(foo foo bar baz) ];
is_deeply [ $hash->values ], [ qw(b c bba 34) ];
}

done_testing;
2 changes: 1 addition & 1 deletion t/multi.t
Expand Up @@ -14,7 +14,7 @@ is ref $hash->{foo}, '';
my @foo = $hash->get_all('foo');
is_deeply \@foo, [ 'a', 'b' ];
is_deeply [ sort keys %$hash ], [ 'bar', 'baz', 'foo' ];
is_deeply [ $hash->keys ], [ 'foo', 'bar', 'baz' ];
is_deeply [ $hash->keys ], [ 'foo', 'foo', 'bar', 'baz' ];
is $hash->{baz} + 2, 35;

is $hash->get_one('bar'), 'baz';
Expand Down

0 comments on commit 9db6f50

Please sign in to comment.