http://www.perlmonks.org?node_id=11106297


in reply to How to Order an Array's Elements to Match Another Array's Element Order

Ok... Something to contemplate...

Firstly, some example program code:-

use warnings; use strict; use Data::Dumper; use Tie::IxHash; my %hash; tie %hash, "Tie::IxHash"; %hash = (); while (my $buf = <DATA>) { chomp($buf); my ($vitem, $project_info) = split(/,/, $buf); my ($project_name, $segment_info) = split(/\|/, my $project_info); my (@segments) = split(/;/, $segment_info); push(@{$hash{$project_name}{$vitem}}, @segments); } print Dumper(%hash); exit(0); # ----------- __DATA__ J_071117,BM:3|12.0-25.2;32.9-88.0 J_070424,BM:3|625-920;1017.905-1178 J_021212,BB:1|123-166;409-455 070526,SWT:1|53.160-59.320;77.720-86.120;370.800-416.800 070609,SWT:1|713.760-1159.200 070616a,SWT:1|0.0-652.0 070616b,SWT:1|401.40-461.800;483.160-490.640;503.400-595.200;602.440-6 +95.400;699.200-882.400 J_071019a,SWT:1|372.925-910.385;927.620-1038.830 J_071019b,SWT:1|268.15-808.330 J_071025,SWT:1|936.215-1659.635 071123_F,SWT:1|45.4550-81.665

...and the output it produces:-

$VAR1 = 'BM:3'; $VAR2 = { 'J_070424' => [ '625-920', '1017.905-1178' ], 'J_071117' => [ '12.0-25.2', '32.9-88.0' ] }; $VAR3 = 'BB:1'; $VAR4 = { 'J_021212' => [ '123-166', '409-455' ] }; $VAR5 = 'SWT:1'; $VAR6 = { '070526' => [ '53.160-59.320', '77.720-86.120', '370.800-416.800' ], '071123_F' => [ '45.4550-81.665' ], 'J_071019a' => [ '372.925-910.385', '927.620-1038.830' ], 'J_071025' => [ '936.215-1659.635' ], '070609' => [ '713.760-1159.200' ], '070616b' => [ '401.40-461.800', '483.160-490.640', '503.400-595.200', '602.440-695.400', '699.200-882.400' ], '070616a' => [ '0.0-652.0' ], 'J_071019b' => [ '268.15-808.330' ] };

As (I) expected/understood, the 'first-level' key is maintained in insertion order. However, subsequent (hash) key items are NOT in insertion order (which I did NOT expect/understand); array items ARE in insertion order.

Ultimately, I want to be able to refer to the hash in a form like:-

@{$hash{$project}{$vitem}}

...realizing that this can be problematic, given that I'm using a couple of different Perl versions and the "keys on reference is experimental at..." issue is (not) present in some cases... but one thing at a time...(!)

Effectively, do something like:-

for each project output "Project: ", project for each vitem in the current project output " VItem: ", vitem for each vitem segment output " Segment: ", segment endfor endfor endfor

...but if you looked at the output, the "VItems" would be in the original order they were shown in the __DATA__ block (within in each project).

Oh.. and something I should have explained earlier... Running all this with Perl v5.20.2, build 2001, under 32-bit Win8.1 OR Perl v5.18.1, under Linux Kernel 3.14.55 (Puppy Linux 32-bit v6.3.2).

Hopefully, this helps explain the context some...