Я пытаюсь реализовать многомерную таблицу с заголовками.
Вот пример для 2D:
< dimension1 >
/\ 'column0' 'column1'
dimension0 'row0' data00 data10
\/ 'row1' data01 data11
Заголовки для строк и столбцов - текст, а данные - что угодно. Я хочу иметь возможность сделать что-то вроде этого (синтаксис может быть другим, я новичок в Perl):
my $table = new table(2); # 2 is the number of dimensions
# the following line creates a new row/column if it didn't exist previously
$table['row0']['column0'] = data00;
$table['row0']['column1'] = data01;
$table['row1']['column0'] = data10;
$table['row1']['column1'] = data11;
# the following line returns the headers of the specified dimension
$table->headers(0);
=> ('row0', 'row1')
Первый вопрос: Есть ли что-то подобное, уже сделанное в CPAN? (прежде чем вы спросите, я искал в течение значительного времени и не нашел ничего подобного)
Второй вопрос: Вот моя попытка, я знаю, что это уродливо и, вероятно, неправильно. Кто-нибудь из экспертов Perl может просмотреть мой код?
package table;
sub new {
my $class = shift;
my $dimensions = shift;
my $self = bless({}, $class);
$self->{dimensions} = $dimensions;
$self->{data} = [];
$self->{headers} = [];
return $self;
}
sub get_dimensions {
my $self = shift;
return $self->{dimensions};
}
# This function creates a header or return its index if it already existed.
# Headers are encoded as an array of hashes so that this is O(1) amortized.
sub header {
my $self = shift;
my $dimension = shift;
my $header = shift;
my $headers = $self->{headers}[$dimension];
if(!defined($headers)) {
$headers = $self->{headers}[$dimension] = {};
}
if(!defined($headers->{$header})) {
$headers->{$header} = scalar keys %$headers;
}
return $headers->{$header};
}
# This function returns the list of headers. Because the headers are
# stored as a hash (`header=>index`), I need to retrieve the keys
# and sort them by value.
sub get_headers {
my $self = shift;
my $dimension = shift;
my $headers = $self->{headers}[$dimension];
return [sort { $headers->{$a} cmp $headers->{$b} } keys %$headers];
}
# This last function stores/retrieves data from the table.
sub data {
my $self = shift;
my $data = $self->{data};
my $dimensions = $self->{dimensions};
for(my $i = 0; $i < $dimensions-1; ++$i) {
my $index = $self->header($i, shift);
if(!defined($data->[$index])) {
$data->[$index] = [];
}
$data = $data->[$index];
}
my $index = $self->header($dimensions-1, shift);
my $value = shift;
if(defined($value)) {
$data->[$index] = $value;
}
return $data->[$index];
}