A piggy bank of commands, fixes, succinct reviews, some mini articles and technical opinions from a (mostly) Perl developer.

Jump to

Quick reference

Showing posts with label array. Show all posts
Showing posts with label array. Show all posts

Surprising behaviour of the perl debugger for wantarray()

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.

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 ]
        ];

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

Perl DBI

This is the one you want:

$ary_ref = $dbh->selectcol_arrayref($statement);

Perl map command

%hash = map { get_a_key_for($_) => $_ } @array;

http://perldoc.perl.org/functions/map.html


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!

PHP arrays

This won't work:
php -r "$a = array( 'c' => array( 'b' => 1 ) );"

But this will:
php -r '$a = Array( "c" => Array( "b" => 1 ) );'

On Mac OSX

PHP debug output

ob_start();
print_r( $xml_object );
$output = ob_get_clean();
$this->logger->debug('output=' . $output);