I have lots of data like this
type1, type2, type3
aax, ert, ddd
asx, eer, kkk
xkk, fff, lll
xxj, vtt, lle
...
and I would really like to be able to "map" between them, so I can go from
type1 -> type2
type1 -> type3
type2 -> type1
type3 -> type1
Example:
type1_to_type2(aax) should return ert
type1_to_type3(asx) should return kkk
type2_to_type3(fff) should return lll
type3_to_type1(lle) should return xxj
What data structure should be used for the data?
And how would such functions look like?
Update: All data is unique.
A version that actually implements the 'type1_to_type2' etc... functions.
#!/usr/bin/perl
use strict;
use warnings;
my $data;
while (<DATA>) {
chomp;
push @$data, [ split ];
}
sub typeX_to_typeY {
my ($x, $y, $str) = @_;
foreach (@$data) {
if ($_->[$x - 1] eq $str) {
return $_->[$y - 1];
}
}
return;
}
sub type1_to_type2 { typeX_to_typeY(1, 2, @_) }
sub type1_to_type3 { typeX_to_typeY(1, 3, @_) }
sub type2_to_type1 { typeX_to_typeY(2, 1, @_) }
sub type2_to_type3 { typeX_to_typeY(2, 3, @_) }
sub type3_to_type1 { typeX_to_typeY(3, 1, @_) }
sub type3_to_type2 { typeX_to_typeY(3, 2, @_) }
# tests
use Test::More tests => 4;
is(type1_to_type2('aax'), 'ert');
is(type1_to_type3('asx'), 'kkk');
is(type2_to_type3('fff'), 'lll');
is(type3_to_type1('lle'), 'xxj');
__DATA__
aax ert ddd
asx eer kkk
xkk fff lll
xxj vtt lle
If all the strings are unique, you can use them as keys in a hash:
my %data = (
aax => ["aax", "ert", "ddd"],
ert => ["aax", "ert", "ddd"],
ddd => ["aax", "ert", "ddd"],
asx => ["asx", "eer", "kkk"],
...
);
sub get_value {
my ($s, $type) = @_;
return $data{$s}[$type-1];
}
print get_value("aax", 2); # "ert"
One approach is to use a database for this sort of thing. Here's an illustration:
use strict;
use warnings;
use DBI;
my $dbh = DBI->connect("dbi:SQLite:dbname=demo_db","","");
# Initialize an SQLite DB with some content.
my @init_db = (
'CREATE TABLE demo (ty1 VARCHAR(5), ty2 VARCHAR(5), ty3 VARCHAR(5));',
'INSERT INTO demo (ty1, ty2, ty3) values ("aax", "ert", "ddd");',
'INSERT INTO demo (ty1, ty2, ty3) values ("asx", "eer", "kkk");',
'INSERT INTO demo (ty1, ty2, ty3) values ("xkk", "fff", "lll");',
'INSERT INTO demo (ty1, ty2, ty3) values ("xxj", "vtt", "lle");',
);
for my $s (@init_db){
$dbh->do($s) or die $!;
}
# Query the data by any field we like.
my $sth = $dbh->prepare('SELECT * FROM demo');
$sth->execute();
my $result = $sth->fetchall_hashref('ty1');
The result is a reference to a hash of hashes, keyed by the value of ty1
and then by the field names in our table. For example:
$result->{xkk} = {
'ty2' => 'fff',
'ty3' => 'lll',
'ty1' => 'xkk'
};
If you're interested in just one particular value of a given field, you can use a more specific query. With this approach it's very easy to write utility methods -- for example, take a field name and a value of interest, and return the results in whatever format is most handy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With