#!/usr/bin/env perl use strict; use warnings; use List::Util qw{first}; use constant { HOUSE => 0, FAMILY => 1, EXTERN => 2, EXTRAS => 3 }; use constant INDEX => qw{HOUSE FAMILY EXTERN EXTRAS}; my @table; while () { push @table, [ split ]; } print crosslink(HOUSE, FAMILY, 9), "\n"; print crosslink(HOUSE, FAMILY, 9), "\n"; print crosslink(FAMILY, HOUSE, 10), "\n"; print crosslink(EXTRAS, EXTERN, '8text'), "\n"; print crosslink(EXTRAS, FAMILY, '8text'), "\n"; print crosslink(HOUSE, EXTRAS, 12), "\n"; print crosslink(HOUSE, EXTRAS, 13), "\n"; { my %cross; sub crosslink { my ($in, $out, $val) = @_; my $key = $in . '-' . $val; if (exists $cross{$key}) { return $cross{$key}[$out]; } print 'Search once only:', "\n"; # for testing only - remove in production my $found = first { $_->[$in] eq $val } @table; return 'Not found! ' . (INDEX)[$in] . ": $val" if ! defined $found; $cross{$key} = $found; return $cross{$key}[$out]; } } __DATA__ 1 2 3 4text 5 6 7 8text 9 10 11 12text 13 14 15 16text