我有一个包含以下数据的表
1.1.1.1 routerA texas
2.2.2.2 routerB texas
3.3.3.3 routerC california在Perl中存储此数据的最佳数据结构是什么?我正在考虑将IP地址作为关键字存储在哈希表中
1.1.1.1
routerA => texas,
2.2.2.2
routerB => texas,
3.3.3.3
routerC => california但是,如果我想获得德克萨斯州的所有IP地址,我的数据结构可能不够灵活。如果我关心德克萨斯州的所有IP地址,有没有更好的存储方式?
发布于 2012-06-05 00:17:44
纯Perl绝对能胜任这项任务。
可以将表看作是记录的数组。用Perl的话来说,这是一个散列引用数组。( AoA有时可能适用,请记住TIMTOWTDI)
每个散列引用的键对应于列/字段名,值将是该特定记录的值。
将OP的示例转换为数据结构:
my @data = (
{
ip => '1.1.1.1',
router => 'routerA',
state => 'texas',
},
{
ip => '2.2.2.2',
router => 'routerB',
state => 'texas',
},
{
ip => '3.3.3.3',
router => 'routerA',
state => 'california',
}
);现在是有趣的部分:
# Give me all IPs in Texas
my @ips_in_texas = map $_->{ip},
grep { $_->{state} =~ /texas/i }
@data;
# How many states does the data cover?
use List::MoreUtils 'uniq';
my $states_covered = uniq( map $_->{state}, @data );
# How many unique IPs in each state?
my %ips_by_state;
$ips_by_state{ $_->{state} }{ $_->{ip} }++ for @data;
print "'$_': ", scalar keys %{ $ips_by_state{$_} }, "\n" for keys %ips_by_state;当我建议这种数据结构时,我经常得到的下意识反应是围绕它对内存的渴望。坦率地说,除非你要处理数百万条记录,否则这不会成为问题。如果是这样的话,DBMS是您寻求的笔尖解决方案,而不是Perl。
发布于 2012-06-04 23:41:04
我知道这不是perl..。但是内存中的SQLite表又如何呢?快速,灵活,便携,甚至持久化。你可以在那里做更复杂的事情,然后查找德克萨斯州的所有IP地址……
发布于 2012-06-04 23:57:47
您的建议使用散列的IP地址作为关键字,这正是我将如何做到这一点。但是,您还必须构建一个独立的、次要的、交叉引用的散列,其中州(如德克萨斯州)是关键字,IP地址是数据。在二级散列中,每个状态都是一个键,而相应的值本身就是一个散列。在内部散列中,键是In,值是虚拟值,通常是值1。
在您的示例中,以下是次要的交叉引用散列:
california
{ 3.3.3.3 => 1 },
texas
{ 1.1.1.1 => 1, 2.2.2.2 => 1 }您可以编写一个简短的子例程/函数/块,从主哈希表构建次要哈希表。如果数据集很大并且经常更新,这会有点困难,但想法是相同的。
如果您首先掌握了Perl几乎太可爱但仍然相当方便的自动生动特性,您会发现更容易编写执行上述操作的代码:请参阅手册页perlreftut和perlref。
https://stackoverflow.com/questions/10884015
复制相似问题