in reply to Re: Parsing an Array of Hashes, Modifying Key/Value Pairs
in thread Parsing an Array of Hashes, Modifying Key/Value Pairs

NetWallah,

Thank you for the tips! I've managed to dig through a bit further and make more sense of what was confusing me. I wound up benching your suggestion against removing key pairs and you were right. Marginally more memory usage, but pretty well moot.

I've got two follow-up questions though

  1. Can you provide me something (link, book, quick write-up, etc) about how to tell while you're coding whether or not you're working with a reference? Or is that just something I'll pick up as I write more code?
  2. What's the difference between (as seen on line 33 in the code below)

Minus the error I'm getting, this is the solution to my initial query.

#! /usr/bin/env perl use XML::Simple; use Data::Dumper; use strict; use warnings; use 5.012; ######## ########### Variables ######## # Array that we'll be holding our cleaned and unique texts in my @textsToKeep; # XML Parser my $xml = new XML::Simple; ######## ########### Subroutines ######## # Filepath is passed to load a hashref # a CLEANED Hashref is returned of the xml we've loaded sub loadFileToHashRef { my $xmlRef = $xml->XMLin($_[0]); while (my ($smsKey, $smsHash) = each @{$xmlRef->{sms}}) { # Each KEY now holds a single HASH. Clone the data we +WANT into @textsToKeep push @textsToKeep, (${$smsHash->{date}}, ${$smsHash->{ +body}}, ${$smsHash->{address}}, ${$smsHash->{type}}); } # Destroy our hashref to free memory undef $xmlRef; } my $hashRef = loadFileToHashRef("xml/sms-20110704030000.xml"); print Dumper @textsToKeep;

As I'm still uncertain about strict references, the solution to this doesn't jump out at me (as I *think* I'm pretty strict about what data I want and in which order) ☺

Can't use string ("1288032888762") as a SCALAR ref while "strict refs" in use at ./parse.pl line 33.

Cheers!

-- Libra

Replies are listed 'Best First'.
Re^3: Parsing an Array of Hashes, Modifying Key/Value Pairs (references)
by LanX (Saint) on May 12, 2013 at 22:01 UTC
    > Can you provide me something (link, book, quick write-up, etc) about how to tell while you're coding whether or not you're working with a reference? Or is that just something I'll pick up as I write more code?

    see perlref and ref

    Perl uses sigils and (de)reference operators to show if your dealing with a ref.

    The default for @arrays and %hashes is what I call their "list form", i.e. you always copy the content when assigning them:

    DB<100> @a=(1,2,3) => (1, 2, 3) DB<101> @b=@a => (1, 2, 3) DB<102> $b[0]=42 => 42 DB<103> $a[0] # @a didn't change => 1

    as you noticed $a[0] accesses the first element of @a, you need $ because $a[0] is a scalar and not an array.

    But the behavior from Python is to default to the "reference form" for arrays and hashes and to the non-reference form for simple variables:

    >>> a=[1,2,3] >>> b=a >>> b[0]=42 >>> a[0] 42

    to achieve this behavior (e.g. to be able to nest data) you need references in Perl and refs are $scalars.

    DB<104> $a=[1,2,3] => [1, 2, 3] DB<105> $b=$a => [1, 2, 3] DB<106> $b->[0]=42 => 42 DB<107> $a->[0] # original changed => 42

    you need an explicit dereference operator -> to distinguish between the array @a and the referenced array in $a (yes they are different) ¹.

    There is also a reference operator \ to get the reference of a variable.

    This way the above example can be written

    DB<108> \@a => [1, 2, 3] DB<109> $b=\@a => [1, 2, 3] DB<110> $b->[0]=666 => 666 DB<111> $a[0] # original changed => 666

    There is an alternative way to dereference by prepending the intended sigil

    DB<112> @$b => (666, 2, 3) # now a (list) not an [array-ref]

    but you need to careful about precedence when dealing with nested structures.

    There is more to say, but this should be enough for the beginning.

    Please ask if you have further questions.

    Cheers Rolf

    ( addicted to the Perl Programming Language)

    1) There are no special sigils to denote a array_ref or a hash_ref in Perl. Which is unfortunate IMO cause one could avoid deref-operators this way! But the keyboard is already exhausted and things like €£¢ are difficult to type. I'm using a naming convention to mark them, e.g. $a_names for array_ref of names.

Re^3: Parsing an Array of Hashes, Modifying Key/Value Pairs
by NetWallah (Canon) on May 13, 2013 at 01:42 UTC
    I think the syntax you are looking for is:
    push @textsToKeep, [ $smsHash->{date}, $smsHash->{body}, $smsHash->{a +ddress} , $smsHash->{type} ]; # Adding ONE entry, which +is an array-ref.
    This makes @textsToKeep an AOA (Array of Array's), which , technically, is an Array of Array-refs.

    You can access individual items as follows:

    my $body_for_third_item = $textsToKeep[2][1]; # Indexes start a 0 my $address_for_second_item = $textsToKeep[1][2];

                 "I'm fairly sure if they took porn off the Internet, there'd only be one website left, and it'd be called 'Bring Back the Porn!'"
            -- Dr. Cox, Scrubs