3

次のデータを含むテーブルがあります

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アドレスを気にする場合、これを保存するためのより良い方法はありますか?

4

3 に答える 3

10

純粋な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-04T16:17:43.630 に答える
4

私は知っています、それはperlではありません...しかし、メモリ内のSQLiteテーブルはどうですか?高速、フレキシベル、ポータブル、さらには永続性。そこでもっと複雑なことをしてから、テキサスのすべてのIPを探すことができます...

于 2012-06-04T15:41:03.803 に答える
4

IPアドレスをキーとしてハッシュのハッシュを使用するというあなたの提案は、まさに私がこれを行う方法です。ただし、別のセカンダリ相互参照ハッシュも作成する必要があります。このハッシュでは、州(テキサスなど)がキーであり、IPアドレスがデータです。二次ハッシュでは、各状態がキーであり、対応する値自体がハッシュです。内側のハッシュでは、キーはIPであり、値はダミー値であり、通常は値1です。

あなたの例では、これが二次的な相互参照ハッシュです:

california
 { 3.3.3.3 => 1 },
texas
 { 1.1.1.1 => 1, 2.2.2.2 => 1 }

プライマリからセカンダリハッシュを構築する短いサブルーチン/関数/ブロックを書くことができます。データセットが大きく、頻繁に更新される場合は少し難しくなりますが、考え方は同じです。

Perlのほとんど可愛すぎるが、それでもかなり便利な自動生存機能を最初に理解すると、上記を実行するコードを記述しやすくなります。マンページperlreftutおよびperlrefを参照してください

于 2012-06-04T15:57:47.380 に答える