带标题的Perl多维表
我正在尝试使用标头实现多维表.
这是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]; } 解决方法
您想要一个“N”维表的结构.我怀疑有一个CPAN模块可以做到这一点,因为它只是不常见的情况.
问题是数据结构增长得非常快,复杂性也是如此. 您可以使用一些数学将N维数组转换为单个维度,从而将N维表存储在单个列表中.假设X表示X维度,X’表示该维度的长度.对于二维表,您可以通过执行以下操作来获取值: X * Y` + Y. 对于三维表X,Y,Z,答案是: X * (Y' * Z') + Y * Z' + Z 对于4维表W,X,答案是: W * (X' * Y' * Z') + X * (Y' + Z') + Y * Z' + Z' (我希望数学是正确的). 因此,对于N维表,我可以想象这样的结构.它将涉及两个不同的类:一个代表维度信息,另一个代表实际数据(包括所有维度). >尺寸(类) >标题(字母数字字符串) > N表(类) >维度数组(维度类对象) 您可以通过查看以获得维度数量: my $numOfDimensions = scalar @{$ntable->{DIMENSIONS}}; 并且,您可以通过查看以下内容获得维度$x的标题: my xDimensionHeading = $ntable->{DIMENSION}->[$x]->{HEADING}; 并且,通过查看该维度的大小: my xDimensionSize = $ntable->{DIMENSION}->[$x]->{SIZE}; 当然,您可以使用真正的面向对象调用,而不是裸引用,但这可以让您了解结构如何工作. 现在,您需要一种将表示单元格位置的整数列表转换为单维数组中单元格位置的方法,并且您将有一种获取和检索数据的方法. 这会是你想要的吗? 编辑
这增加了许多复杂性…… 我们需要在Dimension类中抛出Size.并且,我们不能使用单维数组来存储我们的数据. 我希望你不要改变表的维度. 我们可以这样做: > N表(类) >尺寸标题列表{DIMENSION} – > [] {DATA}列表是列表的链接,具体取决于表的深度.例如: my data_3D = $table_3D->{DATA}->[$x]->[$y]->[$z]; my data_2D = $table_2D->{DATA}->[$x]->[$y]; 维度的数量是标量@ {$table-> {DIMENSION}}. 问题是如何以维度中立的方式访问数据.我可能需要2个,3个,4个或更多维度,而且我必须在某种程度上构建我的地址以将其拉出来. 我们可以有某种循环机制.我们在@coordinates中获得坐标列表,然后查看每个坐标.最后一个将指向数据.其余的只是对另一个数组的另一个引用. my $data = pop @coordinates; #First Coordinate $data = $table->[$data]; #Could be data if 1D table,could be a reference foreach my $coordinate (@coordinates) { die qq(Not enough coordinates) if ref $data ne 'ARRAY'; $data = $data->[$coordinate]; #Could be data,could be a reference } # Cell value is in $data 也可以构建坐标列表,然后对其进行评估.再次完全未经测试: $coordinates = "[" . join ("]->[" => @coordinates . "]"; 如果有三个坐标,那就是 $coordinates = "[$x]->[$y]->[$z]"; 我不确定一维数组如何工作…… 从那里,您可以构建一个语句并在其上使用eval并获取数据. 你必须有几种方法. >设置尺寸 这更像是一次大脑转储,但我认为这可能有用.您没有任何设置表格尺寸,它可能适用于任何N维表格. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |