rael438 has asked for the wisdom of the Perl Monks concerning the following question:

A gentleman I know wrote some code to parse a file and then feed the values into a hash. I seem to be retarded with perl hash. Could someone give me an example of pulling data from this? Here is his documentation: EDIT: i updated with his full pm
package AuctioneerParse; # AuctioneerParse v2.1 - Perl Module to Parse Auctioneer LUA Data File +s # Copyright 2005, 2006 Christopher J. Carlson <c@rlson.net>. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # Changelog # ------------------------------- # # v2.1 - Fixed Realms that have spaces or apostrophes in their name # # v2.0 - Initial Rewrite # # Formats Explained (data Section) # -------------------------------- # ["9968:1201:0"] = "6:6:120210:0:0:6:167800|20000x2:26000:31600:33600 +:36600", # -------------------------------------------------------------------- +-------- # # 9968 = Item ID (ie Wool Cap) # 1201 = Random ID (ie of the Bear) # 0 = Enchant ID (ids any Enchants or Armor Kits Applied) # -------- # # 6 = Count # 6 = Minimum Count # 120210 = Minimum Price # 0 = Bid Count # 0 = Bid Price # 6 = Buy Count # 167800 = Total Price # -------- # # 20000x2 = A 2 Stack for 20000 # 31600 = A 1 Stack for 31600 # 33600 = A 1 Stack for 33600 # 33600 = A 1 Stack for 36600 # -------- # # Note on Prices: # 36600 = 3 Gold, 66 Silver, and 00 Bronze. Break it up. # # -------------------------------------------------------------------- +-------- # # # Returned Hash Format: # # {14260:771:0} = { # 'allPrices' => [ # 8900, # 22000 # ], # 'itemMetrics' => '2:2:20100:0:0:2:30900', # 'bidCount' => '0', # 'minPrice' => '20100', # 'itemClass' => '2', # 'buyPrice' => '30900', # 'buyCount' => '2', # 'numCount' => '2', # 'minCount' => '2', # 'itemName' => 'Bloodwoven Bracers of the Owl', # 'itemPrices' => '8900:22000', # 'bidPrice' => '0', # 'randomID' => '771', # 'baseNum' => '14260', # 'mean' => '400', # 'median' => '300', # 'mode' => '400', # 'stdDev' => '100' # } # -------------------------------------------------------------------- +-------- # use strict; use Statistics::Descriptive; my $DEBUG = 0; sub new { my ($class, %args) = @_; my $self = bless {}, ref($class) || $class; return $self; } sub loadFile { my $self = shift; my $file = shift; open (DATA, "$file") || die ("Can't Find File ($file): $!\n"); my $LUAHash; my $depth = 0; my @obj; while (<DATA>) { chomp; if (m/\["?([A-Za-z0-9\-\' ]+)"?\] = {/) { push @obj, $1; print "[$depth] Adding $1 (@obj)\n" if $DEBUG; $depth++; next; } if (m/},$/) { my $a = pop @obj; print "[$depth] Removing: $a (@obj)\n" if $DEBUG; $depth--; next; } s/^\s+//; my ($key, $value) = split / = /; $key =~ s/(\["|"\])//g; $value =~ s/("|,)//g; if (scalar(@obj) == 3) { $LUAHash->{$obj[0]}->{$obj[1]}->{$obj[2]}->{$key} = $value +; } if (scalar(@obj) == 2) { $LUAHash->{$obj[0]}->{$obj[1]}->{$key} = $value; } if (scalar(@obj) == 1) { $LUAHash->{$obj[0]}->{$key} = $value; } } if ($depth != 0) { print STDERR "Warning: Corrupted Auctioneer.lua File Detected. +\n"; } return $LUAHash; } sub loadItems { my $self = shift; my $luaHASH = shift; my $itemHash; foreach my $RealmFaction (keys %{$luaHASH->{data}}) { foreach my $item (keys %{$luaHASH->{data}->{$RealmFaction}}) { my $itemNum = $item; my $itemData = $luaHASH->{data}->{$RealmFaction}->{$item}; my ($baseNum, $randomID, $enchantID) = split /:/, $itemNum +; my ($itemMetrics, $itemPrices) = split(/\|/, $itemData); my @Metrics = split /:/, $itemMetrics; my @uniformPrices; my @Prices = split /:/, $itemPrices; foreach my $price (@Prices) { if ($price =~ m/x\d+/) { my ($entityPrice, $entityCount) = split /x/,$price +; for (1..$entityCount) { push @uniformPrices, $entityPrice; } } else { push @uniformPrices, $price; } } $itemHash->{$RealmFaction}->{$itemNum}->{allPrices} = [ @u +niformPrices ]; my $stat = Statistics::Descriptive::Full->new(); $stat->add_data(@uniformPrices); $itemHash->{$RealmFaction}->{$itemNum}->{mean} = $stat->me +an() || 0; $itemHash->{$RealmFaction}->{$itemNum}->{stdDev} = $stat-> +standard_deviation() || "0"; $itemHash->{$RealmFaction}->{$itemNum}->{median} = $stat-> +median() || 0; $itemHash->{$RealmFaction}->{$itemNum}->{mode} = $stat->mo +de() || 0; $itemHash->{$RealmFaction}->{$itemNum}->{itemMetrics} = $i +temMetrics; $itemHash->{$RealmFaction}->{$itemNum}->{itemPrices} = $it +emPrices; $itemHash->{$RealmFaction}->{$itemNum}->{numCount} = $Metr +ics[0]; $itemHash->{$RealmFaction}->{$itemNum}->{minCount} = $Metr +ics[1]; $itemHash->{$RealmFaction}->{$itemNum}->{minPrice} = $Metr +ics[2]; $itemHash->{$RealmFaction}->{$itemNum}->{bidCount} = $Metr +ics[3]; $itemHash->{$RealmFaction}->{$itemNum}->{bidPrice} = $Metr +ics[4]; $itemHash->{$RealmFaction}->{$itemNum}->{buyCount} = $Metr +ics[5]; $itemHash->{$RealmFaction}->{$itemNum}->{buyPrice} = $Metr +ics[6]; $itemHash->{$RealmFaction}->{$itemNum}->{baseNum} = $baseN +um; $itemHash->{$RealmFaction}->{$itemNum}->{randomID} = $rand +omID; $itemHash->{$RealmFaction}->{$itemNum}->{enchantID} = $enc +hantID; } foreach my $itemNum (keys %{$luaHASH->{info}}) { my $itemData = $luaHASH->{info}->{$itemNum}; my ($itemClass, $itemName) = split /\|/, $itemData; if (exists($itemHash->{$RealmFaction}->{$itemNum})) { $itemHash->{$RealmFaction}->{$itemNum}->{itemName} = $ +itemName; $itemHash->{$RealmFaction}->{$itemNum}->{itemClass} = +$itemClass; } } } return $itemHash; } 1;

Edit: g0n - readmore tags

Replies are listed 'Best First'.
Re: some help w/ hashes
by Zaxo (Archbishop) on Jun 02, 2006 at 02:26 UTC

    Given a hash reference, which is what's returned by the curlies with the data inside, you'd read the data with the ->{} construct.

    print $hashref->{'itemName'}, $/;
    The business inside the left-side curlies looks like "baseNum", "randomID" and something else stuck together to make a key to a higher-level hash. If so, you'll need to find out its name, but that barely changes how you get the data out. If the bigger hash is referenced by $its_name,
    print $its_name->{$the_key}{'itemName'}, $/;
    Some of the data ("allPrices") refers to an array, others seem to be lists presented csv style. You probably need a better spec to decypher all that.

    After Compline,
    Zaxo

Re: some help w/ hashes
by davido (Cardinal) on Jun 02, 2006 at 02:18 UTC

    What is {14260:771:0}? You can't assign a hash ref to that.

    Let's assume you've got a hash ref with some sensible name ({14260:771:0} isn't a syntactically correct variable name), and you want to extract some data from it. ...In your example, it does look like you're working with a hash ref, not a named hash, so I'll proceed on that assumption.

    my $href = { 'allPrices' => [ 8900, 22000 ], 'itemMetrics' => '2:2:20100:0:0:2:30900', 'bidCount' => '0', 'minPrice' => '20100', 'itemClass' => '2', 'buyPrice' => '30900', 'buyCount' => '2', 'numCount' => '2', 'minCount' => '2', 'itemName' => 'Bloodwoven Bracers of the Owl', 'itemPrices' => '8900:22000', 'bidPrice' => '0', 'randomID' => '771', 'baseNum' => '14260', 'mean' => '400', 'median' => '300', 'mode' => '400', 'stdDev' => '100' }; print $href->{stdDev}, "\n"; print $href->{allPrices}[0], "\n";

    And the output is:

    100 8900

    I hope this helps. You will find this much and more in perlintro. This is required reading that will help you prior to following up in this thread with further clarification on your question.


    Dave

Re: some help w/ hashes
by GrandFather (Saint) on Jun 02, 2006 at 02:57 UTC

    Note that allPrices is a reference to an array and ought be handled as a special case.

    use strict; use warnings; my $itemHash = { '14260:771:0' => { 'allPrices' => [ 8900, 22000 ], 'itemMetrics' => '2:2:20100:0:0:2:30900', 'bidCount' => '0', 'minPrice' => '20100', 'itemClass' => '2', 'buyPrice' => '30900', 'buyCount' => '2', 'numCount' => '2', 'minCount' => '2', 'itemName' => 'Bloodwoven Bracers of the Owl', 'itemPrices' => '8900:22000', 'bidPrice' => '0', 'randomID' => '771', 'baseNum' => '14260', 'mean' => '400', 'median' => '300', 'mode' => '400', 'stdDev' => '100', }, }; for my $RealmFaction (keys %$itemHash) { for my $item (keys %{$itemHash->{$RealmFaction}}) { print "$item => $itemHash->{$RealmFaction}{$item}\n"; } }

    Prints:

    stdDev => 100 mode => 400 itemMetrics => 2:2:20100:0:0:2:30900 median => 300 minPrice => 20100 minCount => 2 itemPrices => 8900:22000 randomID => 771 baseNum => 14260 allPrices => ARRAY(0x1f125f4) bidCount => 0 mean => 400 itemClass => 2 numCount => 2 buyCount => 2 buyPrice => 30900 itemName => Bloodwoven Bracers of the Owl bidPrice => 0

    DWIM is Perl's answer to Gödel