Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/scheme/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将Perl哈希转换为更灵活的数据结构?_Perl_Data Structures_Oop - Fatal编程技术网

如何将Perl哈希转换为更灵活的数据结构?

如何将Perl哈希转换为更灵活的数据结构?,perl,data-structures,oop,Perl,Data Structures,Oop,在一个快速而肮脏的Perl脚本中,我有一个如下的数据结构: $tax_revenue{YEAR}{STATE}{GOVLEV}{TAX} = integer YEAR: 1900 .. 2000 STATE: AK, AL, ... WY GOVLEV: state, local TAX: type of tax (income, sales, etc.) 哈希键采用如下值: $tax_revenue{YEAR}{STATE}{GOVLEV}{TAX} = integer YEAR: 19

在一个快速而肮脏的Perl脚本中,我有一个如下的数据结构:

$tax_revenue{YEAR}{STATE}{GOVLEV}{TAX} = integer
YEAR: 1900 .. 2000
STATE: AK, AL, ... WY
GOVLEV: state, local
TAX: type of tax (income, sales, etc.)
哈希键采用如下值:

$tax_revenue{YEAR}{STATE}{GOVLEV}{TAX} = integer
YEAR: 1900 .. 2000
STATE: AK, AL, ... WY
GOVLEV: state, local
TAX: type of tax (income, sales, etc.)
此外,哈希键是唯一的。例如,
TAX
参数的值与另一个参数的值不冲突

我正在启动一个处理这些数据的中型项目,我希望以更灵活的方式实现数据结构。我还不知道我需要的所有数据检索功能,但以下是一些示例:

# Specify the parameters in any order.
Tax_rev( qw(1902 WY state property) );
Tax_rev( qw(state property 1902 WY) );

# Use named parameters.
Tax_rev(year => 1902, state => 'WY', govlev => 'state', tax => 'property');

# Use wildcards to obtain a list of values.
# For example, state property tax revenue in 1902 for all states.
Tax_rev( qw(1902 * state property) );

我最初的倾向是将数据存储为散列,并构建一个或多个实用函数(可能作为类的一部分)来检索值。但后来我想知道是否有更好的策略——除了散列之外,还有其他存储底层数据的方法。任何关于如何解决这个问题的建议都将不胜感激。

我建议您研究对象系统,例如。学习曲线不会太陡(或根本不会太陡),其好处将是巨大的。您可以从以下内容开始:

package MyApp;

use Moose; # use strict automagically in effect

has 'year'   => ( is => 'ro', isa => 'Int', required => 1 );
has 'state'  => ( is => 'ro', isa => 'Str', required => 1 );
has 'govlev' => ( is => 'ro', isa => 'Str', required => 1 );
has 'tax'    => ( is => 'ro', isa => 'Str', required => 1 );
然后在主程序中:

use MyApp;

my $obj = MyApp->new(
    year   => 2000,
    state  => 'AK',
    govlev => 'local',
    tax    => 'revenue'
);

# ...
使用MooseX::Types的灵活性,您可以继续声明自己的类型类,使用枚举等


一旦使用Moose,您就再也不会回头看:)

如果您想要纯Perl实现,您可以构建一个哈希数组:

my @taxdata = (
    { year => 1902, state => 'WY', level => 'state', type => 'property', amount => 500 },
    # ...
);

my @matches = grep {
    $_->{year}  == 1902    &&
    $_->{level} eq 'state' &&
    $_->{type}  eq 'property'
} @taxdata;
如果您想对其运行任意查询,这是灵活的,但如果您想能够访问特定记录,则速度较慢


更好的解决方案可能是使用一个表的数据库,其中每一行都包含您列出的字段。然后,您可以编写一个SQL查询来根据任意条件提取数据。您可以使用模块来处理连接。

如果您不打算使用对象,我认为数据结构会很好地工作

下面是一个
Tax\u rev()
的示例。它不是全功能的,但您可以按任意顺序为它提供4个参数。如果您实际使用它,您可能需要检查输入

my $result = Tax_rev( \%data, qw(state property 1902 WY) );


请考虑将数据放入数据库中。然后,您就可以灵活地运行任何需要的查询(通过DBI或SQL的命令行界面)以及获取数据结构,这些数据结构适用于生成给定年份内各州或各州的税收报告,这些州的名称以字母“W”等开头。我假设数据已经采用某种字符分隔格式(制表符、逗号、管道等)因此,可以轻松地批量导入SQLite DB,从而节省一些工作和代码。

查看:“对深度嵌套结构元素的简单、临时访问”。它似乎正是你想从
税务_rev
得到的:

use Data::Diver qw( Dive );

...
$tax_revenue{ 1900 }{ NC }{ STATE }{ SALES } = 1000;
...

  Dive( \%Hash, qw( 1900 NC STATE SALES ) ) => 1000;
  Dive( \%Hash, qw( 1901 NC STATE SALES ) ) => undef;

驼鹿并不是解决所有问题的唯一办法。他没有东西。他没有任何行为。他有数据。你可以通过从@taxdata数组构建你已经拥有的哈希表来扩充这个解决方案。这将以非常类似perl的方式为您提供灵活的查询,以及对特定记录的快速查找。