http://qs321.pair.com?node_id=296224


in reply to Multidimensional array of hashes

You can use a single hash to store all of this:
open CATEGORY, "categories.txt"; # ...or whatever... foreach $line ( <CATEGORY> ) { @ITEMS = split /\|/, $line; foreach $item ( @ITEMS ) { ($value, $key) = split /,/, $item; $LIST{$key} = $value; } } close CATEGORY; open DESC, "descriptions.txt"; # Same code as above, except key/value pairs are reversed. foreach $line ( <DESC> ) { @ITEMS = split /\|/, $line; foreach $item ( @ITEMS ) { ($key, $value) = split /,/, $item; $LIST{$key} = $value; } } close DESC; # Now arrange for the output. open OUTFILE, ">output.txt"; foreach $reference ( sort keys %LIST ) { # Sometimes, it's a new category. These are most important. if ( $reference =~ /^\'\w\w\'$/ ) { print OUTFILE "\n"; } else { print OUTFILE "|"; } print OUTFILE "$reference,$LIST{$reference}"; }

That should do it. Since they're sorted, your category references will always precede your item references. Since the code above checks for that first, you'll start the new line just in time to deal with that item.

Every printed item is preceded by the delimiter it needs. Newlines for a new category, pipes for a new item. That way you don't get extra trailing separators.

There's no error checking code in here, though. If your two input files aren't pristine, you'll get some junk in there. Also, your category references *must* be two alpha characters. If you change that, you might need to change the pattern for recognizing a new category to something more flexible like simply ruling out an item:

if ( $reference !~ /^\'\w+\d+\'$/ ) { # ... }

If it isn't an item, maybe it's a category. :-)

Hope that helps!

--Rhys

edited: Sat Oct 4 12:59:29 2003 by jeffa - s/pre/code/ig