第三章Perl言語(四)-ハッシュ、強制変換

6131 ワード

ハッシュ
ハッシュは、1つのデータのセットを別のデータのセットに対応させることを目的とする集約データ構造である.ハッシュはデータのフォーマットに少し小さな要求があります.キーは文字列で、値はスカラー値でなければなりません.他のプログラミング言語でも、このデータ構造はハッシュテーブル、関連配列、辞書などと呼ばれています.
ハッシュの最も重要な特性は、キーが唯一であることです.キーとキーの間は無秩序です.
ハッシュの宣言
ハッシュは記号%を使用します.ハッシュを宣言します.
my %favorite_flavors;

ハッシュの単一要素にアクセスするには、記号$を使用し、キーを{}で囲みます.
割り当て:
my %favorite_flavors;
$favorite_flavors{Gabi} = 'Dark chocolate raspberry';
$favorite_flavors{Annette} = 'French vanilla';

my %favorite_flavors = (
'Gabi', 'Dark chocolate raspberry',
'Annette', 'French vanilla',
);

太い矢印を使用すると、より明確になります.
my %favorite_flavors = (
Gabi => 'Dark chocolate raspberry',
Annette => 'French vanilla',
);

太い矢印は、前の(裸の文字)文字を自動的に引用符で囲みます.
sub name { 'Leonardo' }
my %address = (
name => '1123 Fib Place'
);
#     name()  


#     name()  
my %address = (
name() => '1123 Fib Place'
);

個々の値にアクセスするには、次の手順に従います.
my $address = $addresses{$name};

#     
my $address = $addresses{Victor};

#        ,      
my $address = $addresses{'Sue-Linn'};

#   “()”       ,    
my $address = $addresses{get_name()};

ハッシュ・キーは文字列でなければなりません.他のタイプのものは強制的に文字列に変換されます.
for my $isbn (@isbns)
{
my $book = Book->fetch_by_isbn( $isbn );

$books{$book} = $book->price;    #         ,     。         
}

ハッシュキーの存在
existsオペレータは、指定されたキーが存在するかどうかを検出し、存在する場合は真を返します.そうでない場合は偽を返します.
my %addresses =
(
Leonardo => '1123 Fib Place',
Utako => 'Cantor Hotel, Room 1',
);
say "Have Leonardo's address"
if exists $addresses{Leonardo};
say "Have Warnie's address"
if exists $addresses{Warnie};

existsオペレータを使用すると、戻り値はキーにのみ関係し、キーに対応する値には関係ありません.
my %false_key_value = ( 0 => '' );
ok( %false_key_value,
'hash containing false key & value
should evaluate to a true value' );

アクセスハッシュ
アクセスキー
for my $addressee (keys %addresses)
{
say "Found an address for $addressee!";
}

アクセス値
for my $address (values %addresses)
{
say "Someone lives at $address";
}

アクセスキー値ペア
while (my ($addressee, $address) = each %addresses)
{
say "$addressee lives at $address";
}

注意:キー値ペアとキー値ペアの間には、特定の順序はありません.
各ハッシュには反復レコードが1つしかないので、eachを複数回使用しないでください.レコーダをリセットする必要がある場合があります.空の文脈でkeysまたはvaluesを使用します.
#      
keys %addresses;
while (my ($addressee, $address) = each %addresses)
{
...
}

ハッシュスライス
配列スライスと同様に、一連のキーと値です.一度に複数の要素を割り当てます.
# %cats already contains elements
@cats{qw( Jack Brad Mars Grumpy )} = (1) x 4;
   :
my %cats = map { $_ => 1 }
qw( Jack Brad Mars Grumpy );

カッコは、ハッシュスライスを使用していることを明確に示しています.
my @buyer_addresses = @addresses{ @buyers };

2つのハッシュをマージするのは簡単です.
my %addresses = ( ... );
my %canada_addresses = ( ... );
@addresses{ keys %canada_addresses }
= values %canada_addresses;

同じキーがあれば、既に存在するものを書き換えます.さらに、対応する順序を保証するには、同じハッシュが操作され、keysとvalues操作の間にハッシュが変更されていない場合にのみ、対応するハッシュが保証される.
空のハッシュ
空のハッシュとは、要素のないハッシュを指します.ブール文脈では偽の値です.要素がある限り真の値です(キーや値の真偽にかかわらず).
use Test::More;
my %empty;
ok( ! %empty, 'empty hash should evaluate false' );
my %false_key = ( 0 => 'true value' );
ok( %false_key, 'hash containing false key
should evaluate to true' );


my %false_value = ( 'true key' => 0 );
ok( %false_value, 'hash containing false value
should evaluate to true' );
done_testing();

スカラー文脈では、ハッシュはハッシュ内部のいくつかの詳細情報(ハッシュバケツの情報)を表す文字列を返し、これは真偽値と一致するので、これらの詳細を気にする必要はありません.リスト文脈では、キー値対リストが返されます.
慣用法
ハッシュの特性のため、私たちはよくこのように使います:リストを再表示します
my %uniq;
undef @uniq{ @items };
my @uniques = keys %uniq;

# @items        ,@uniques     
#        undef            undef。

カウント
my %ip_addresses;
while (my $line = )
{
chomp $line;
my ($ip, $resource) = analyze_line( $line );
$ip_addresses{$ip}++;
...
}

キャッシュ
{
my %user_cache;
sub fetch_user
{
my $id = shift;
$user_cache{$id} //= create_user($id);    #         
return $user_cache{$id};
}
}

デフォルト値:
sub make_sundae
{
my %parameters = @_;
$parameters{flavor} //= 'Vanilla';
$parameters{topping} //= 'fudge';
$parameters{sprinkles} //= 100;
...
}


sub make_sundae
{
my %parameters =
(
flavor => 'Vanilla',
topping => 'fudge',
sprinkles => 100,
@_,
);
...
}

ハッシュのロック
ハッシュキーや値を変更しないように、ハッシュを保護したい場合があります.ハッシュ全体を読み取り専用などにしたい.これらのニーズがあれば、Hash::Utilモジュールを試してみることをお勧めします.きっとあなたの要求を満たすことができます.
強制変換
Perlでは,以前に述べた文脈がタイプの強制変換をもたらす可能性があるなど,強制変換が発生する場合がある.
ブール強制
一般的には、条件式ではブール型に強制的に変換されます.
文字列の強制
eq,cmpのような文字列操作関数を使用すると、強制的に文字列タイプに変換されます.
数値強制
==などの数値オペレータを使用すると、数値タイプに強制的に変換されます.
参照の強制
デリファレンスオペレータを使用すると、強制的にリファレンスタイプに変換されます.
my %users;
$users{Brad}{id} = 228;
$users{Jack}{id} = 229;
#      ,    

キャッシュの強制
Perlが値を格納するときの内部には、文字列部分と数値部分の2つのスロットがあります.文字列は、内部の数値部分を変更するのではなく、内部の文字列部分に文字列値を追加します.同様に、文字列をデジタル化すると、内部で表される数値部分が埋め込まれ、内部の文字列部分は変更されません.Perlの操作は必ず自分の傾向がありますが、いったいどの部分を優先して使うのでしょうか.ブールタイプは文字列に傾いています.たとえば、値が内部表現(所望の形式ではない)をキャッシュしている場合があります.この場合、暗黙的な変換を使用すると、結果は望ましくない可能性があります.これは極めて珍しく、ほとんど遭遇しません.しかし、この詳細を知っておくと、いつか役に立つかもしれません.
にへんすう
Perlの値は内部では天然に単一の部分から構成されていないことは前述したように分かっている.二変数という形式により,ユーザはこの特性を直接使用することができる.システムモジュールScalar::Utilは関数dualvar()を提供し、この関数を通じてPerlの強制ポリシー(暗黙的な変換)を迂回し、変数の文字列と数値部分を直接操作することができます.
use Scalar::Util 'dualvar';
my $false_name = dualvar 0, 'Sparkles & Blue';
say 'Boolean true!' if !! $false_name;
say 'Numeric false!' unless 0 + $false_name;
say 'String true!' if '' . $false_name;