use warnings; use strict; use Data::Dump; my %expensive_lookup = ( math01 => { instructor=>'alice' }, sci99 => { instructor=>'bob' }, gym55 => { instructor=>'carol' }, cs101 => { instructor=>'larry' }, ); my %students = ( sid01 => [qw/ math01 gym55 /], sid007 => [qw/ gym55 sci99 /], sid42 => [qw/ cs101 math01 /], ); my %catalog = (); for my $student_id (keys %students) { for my $course_number ( @{ $students{$student_id} } ) { if ( not exists $catalog{$course_number} ) { $catalog{$course_number} = $expensive_lookup{$course_number}; $catalog{$course_number}{course_number} = $course_number; } $course_number = $catalog{$course_number}; } } dd \%catalog, \%students; __END__ do { my $a = { cs101 => { course_number => "cs101", instructor => "larry" }, gym55 => { course_number => "gym55", instructor => "carol" }, math01 => { course_number => "math01", instructor => "alice" }, sci99 => { course_number => "sci99", instructor => "bob" }, }; ( $a, { sid007 => [$a->{gym55}, $a->{sci99}], sid01 => [$a->{math01}, $a->{gym55}], sid42 => [$a->{cs101}, $a->{math01}], }, ); }