如何一个Perl哈希的哈希值转换为更灵活的数据结构?(How to convert a Perl h

2019-06-26 19: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参数与另一其他参数的值冲突。

我开始一个中型项目,这个数据工作,我想实现更灵活的方式的数据结构。 我不知道所有的数据检索功能,我需要的是,但这里有一些例子:

# 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) );

我最初的倾向是保持存储数据的哈希的哈希值,并建立一个或多个效用函数(可能为类的一部分)来获取值。 但我不知道是否有更好的策略 - 存储不是一个哈希的哈希值等基本数据的某种方式。 关于如何解决这个问题的任何建议,将不胜感激。

Answer 1:

如果你想要一个纯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查询根据任意的条件来提取数据。 您可以使用DBI模块来处理连接。



Answer 2:

请考虑将数据在SQLite的数据库。 然后,你有适合于针对由国家税款报告或通过税收或税收某一年的所有国家任何你想要的查询运行的灵活性(通过DBI或只是命令行界面SQL)和获取数据结构国家名称开头“W”等等等等的信我相信数据已经在某种字符分隔的格式(选项卡,逗号,管道等),因此可以很容易地进行本体导入到一个SQLite数据库,节省了一些工作,代码上结束。



Answer 3:

我劝你寻找到物体的系统,如驼鹿 。 学习曲线不是太陡(或陡峭的话)和效益将是巨大的。 你会喜欢的东西开始:

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 ::类型的灵活性,你可以去上声明自己的类型类,用枚举,等等。

一旦你去驼鹿,你永远不回头:)



Answer 4:

看看Data::Diver :“简单,即席深入嵌套结构的元素的访问权限。” 这似乎做的正是你想从什么Tax_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;


Answer 5:

如果你不打算使用的对象,我认为数据结构会工作得很好。

这里是一个例子Tax_rev() 它不是全功能的,但你可以给它的4个参数以任意顺序。 如果你真的使用它,你可能要检查的输入。

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

use strict;
use warnings;
use 5.010;


文章来源: How to convert a Perl hash-of-hashes to a more flexible data structure?