When you are running a perl script in the debugger, do not expect wantarray() to return the same thing it would if not running in the debugger.
If you break execution at a breakpoint, wantarray() seems to return 1 when it wouldn't otherwise.
A piggy bank of commands, fixes, succinct reviews, some mini articles and technical opinions from a (mostly) Perl developer.
Jump to
Showing posts with label array. Show all posts
Showing posts with label array. Show all posts
Determine differences in an array with Perl
Not just checking whether or not two arrays are the same, but finding out how they are different, i.e. what has been added and what has been taken away:
use Algorithm::Diff 'sdiff';
use Data::Dumper;
my @a = (1, 2, 3, 4);
my @b = (2, 3, 4, 5);
my @c = sdiff(\@a, \@b);
print Dumper(\@c);
Output:
$VAR1 = [
[ '-', 1, '' ],
[ 'u', 2, 2 ],
[ 'u', 3, 3 ],
[ 'u', 4, 4 ],
[ '+', '', 5 ]
];
(source)
However, if comparing (a b c) with (c b a), Algorithm::Diff::sdiff will fail to realise that nothing has been added or removed. A simpler algorithm might be:
sub determine_changes {
my ($old, $new) = @_;
# Compare two lists
my %old_lookup = map { $_ => 1 } @$old;
my %new_lookup = map { $_ => 1 } @$new;
my @added = grep { ! $old_lookup{$_} } @$new;
my @removed = grep { ! $new_lookup{$_} } @$old;
my @changes;
push @changes, map { { item => $_, operation => 'add' } } @added;
push @changes, map { { item => $_, operation => 'remove' } } @removed;
my @sorted_changes = sort { $a->{item} cmp $b->{item} } @changes;
return \@sorted_changes;
}
use Algorithm::Diff 'sdiff';
use Data::Dumper;
my @b = (2, 3, 4, 5);
my @c = sdiff(\@a, \@b);
print Dumper(\@c);
Output:
$VAR1 = [
[ '-', 1, '' ],
[ 'u', 2, 2 ],
[ 'u', 3, 3 ],
[ 'u', 4, 4 ],
[ '+', '', 5 ]
];
You can see that 1 has a '-' indicating it has been removed, and 5 has a '+' indicating it has been added. The other items have a 'u', indicating they are unchanged.
(source)
However, if comparing (a b c) with (c b a), Algorithm::Diff::sdiff will fail to realise that nothing has been added or removed. A simpler algorithm might be:
sub determine_changes {
my ($old, $new) = @_;
# Compare two lists
my %old_lookup = map { $_ => 1 } @$old;
my %new_lookup = map { $_ => 1 } @$new;
my @added = grep { ! $old_lookup{$_} } @$new;
my @removed = grep { ! $new_lookup{$_} } @$old;
my @changes;
push @changes, map { { item => $_, operation => 'add' } } @added;
push @changes, map { { item => $_, operation => 'remove' } } @removed;
my @sorted_changes = sort { $a->{item} cmp $b->{item} } @changes;
return \@sorted_changes;
}
Get unique values from an array in Perl
# Unique an array
@unique_list = keys %{{ map { $_ => 1 } @big_list }}; # aka dedupe a list
# Unique a hash on a specified key 'id'
@unique_list = values %{{ map { $_->{id} => $_ } %big_hash }};
Explanation
@unique_list = keys %{{ map { $_ => 1 } @big_list }}; # aka dedupe a list
# Unique a hash on a specified key 'id'
@unique_list = values %{{ map { $_->{id} => $_ } %big_hash }};
Explanation
Elementary JSON
{
"Image": {
"Width":800,
"Height":600,
"Title":"View from 15th Floor",
"Thumbnail":
{
"Url":"http:\/\/scd.mm-b1.yimg.com\/image\/481989943",
"Height": 125,
"Width": "100"
},
"IDs":[ 116, 943, 234, 38793 ]
}
}
Thanks Yahoo!
Labels:
array,
data,
hash,
javascript,
json
Subscribe to:
Posts (Atom)