Skip to content

Instantly share code, notes, and snippets.

@ytez
Last active October 9, 2019 06:13
Show Gist options
  • Save ytez/9da7ad1148060c9539e8118461dfbf87 to your computer and use it in GitHub Desktop.
Save ytez/9da7ad1148060c9539e8118461dfbf87 to your computer and use it in GitHub Desktop.
[Perlメモ] Hash::Ordered 使ってみる

※作成中 [ 2019-10-08 ]

参考

概要

  • Perl で順序つきハッシュを使いたい
  • Hash::Ordered というものがあったので試してみた

インストール

  • cpan で入る
$ cpan -i Hash::Ordered

SYNOPSIS をさらってみる

実行条件

use 5.20.1;
use warnings;
use utf8;
use Data::Dumper 'Dumper';

use Hash::Ordered;

key/value をひとつ追加

my $oh = Hash::Ordered->new( a => 1 );
say Dumper($oh);

=pod
$VAR1 = bless( [
                 { 'a' => 1 },
                 [ 'a' ],
                 undef, 0, 0
               ], 'Hash::Ordered' );
=cut

ハッシュと配列を共に内部に持っている様子。いいね。

値を取り出す

say $oh->get( 'a' ); # 1
say $oh->[0]->{'a'}; # 上記構造を見る限りこれと同等

値を上書き

$oh->set( 'a' => 2 ); # $oh->[0]->{'a'} = 2
say $oh->get( 'a' ); # 2
say Dumper($oh);

=pod
$VAR1 = bless( [
                 { 'a' => 2 },
                 [ 'a' ],
                 undef, 0, 0
               ], 'Hash::Ordered' );
=cut

キー存在チェック

say $oh->exists( 'a' ); # 1
say $oh->exists( 'b' ); # '' (zero-length)

key/value 削除

my $val = $oh->delete( 'a' );
say $val; # 2
say Dumper($oh);

=pod
$VAR1 = bless( [
                 {},
                 [],
                 undef,
                 0,
                 0
               ], 'Hash::Ordered' );
=cut

キーを指定して削除 → 値が返る。

複数の key/value の組を push

$oh->push( 'a' => '', 'b' => '' );
$oh->push( qw/c う d え/ );
say Dumper($oh);

=pod
$VAR1 = bless( [
                 {
                   'a' => "\x{3042}", # あ
                   'c' => "\x{3046}", # う
                   'd' => "\x{3048}", # え
                   'b' => "\x{3044}"  # い
                 },
                 [
                   'a',
                   'b',
                   'c',
                   'd'
                 ],
                 undef,
                 0,
                 0
               ], 'Hash::Ordered' );
=cut

複数の key/value の組を unshift

$oh->unshift( qw/C ぅ D ぇ/ );
$oh->unshift( 'A' => '', 'B' => '' );
say Dumper($oh);

=pod
$VAR1 = bless( [
                 {
                   'D' => "\x{3047}",
                   'd' => "\x{3048}",
                   'A' => "\x{3041}",
                   'a' => "\x{3042}",
                   'B' => "\x{3043}",
                   'b' => "\x{3044}",
                   'C' => "\x{3045}",
                   'c' => "\x{3046}"
                 },
                 [
                   'A',
                   'B',
                   'C',
                   'D',
                   'a',
                   'b',
                   'c',
                   'd'
                 ],
                 undef,
                 0,
                 0
               ], 'Hash::Ordered' );
=cut

#### キーのみ, 値のみ, 両方 の配列取得
```perl
my @keys = $oh->keys();
say encode_utf8( join ', ', @keys );
# A, B, C, D, a, b, c, d

my @vals = $oh->values();
say encode_utf8( join ', ', @vals );
# ぁ, ぃ, ぅ, ぇ, あ, い, う, え

my @keyvals = $oh->as_list();
say encode_utf8( join ', ', @keyvals );
# A, ぁ, B, ぃ, C, ぅ, D, ぇ, a, あ, b, い, c, う, d, え

key/value の組を pop/shift

my ($key, $value) = $oh->pop();
say encode_utf8( sprintf "poped: key='%s', value='%s'", $key, $value);

($key, $value) = $oh->shift();
say encode_utf8( sprintf "shifted: key='%s', value='%s'", $key, $value);

say encode_utf8( sprintf "after: %s", join( ', ', $oh->as_list()) );

=pop
poped: key='d', value='え'
shifted: key='A', value='ぁ'
after: B, ぃ, C, ぅ, D, ぇ, a, あ, b, い, c, う
=cut

イテレータ

my $iter = $oh->iterator();
my $n = 0;
while( my ( $k, $v ) = $iter->() ) {
  say encode_utf8( sprintf "[%d] key='%s' value='%s'", $n++, $k, $v);
}

=pop
[0] key='B' value='ぃ'
[1] key='C' value='ぅ'
[2] key='D' value='ぇ'
[3] key='a' value='あ'
[4] key='b' value='い'
[5] key='c' value='う'
=cut

※作成中

#!/usr/bin/env perl
use 5.20.1;
use warnings;
use utf8;
use Data::Dumper 'Dumper';
# use Devel::Peek 'Dump';
use Encode 'encode_utf8';
use Hash::Ordered;
say encode_utf8( '# key/value をひとつ追加' );
my $oh = Hash::Ordered->new( a => 1 );
say Dumper($oh);
=pod
$VAR1 = bless( [
{ 'a' => 1 },
[ 'a' ],
undef, 0, 0
], 'Hash::Ordered' );
=cut
say encode_utf8( '# 値を取り出す' );
say $oh->get( 'a' ); # 1
say $oh->[0]->{'a'}; # これでも同じ
say encode_utf8( '# 値を上書き' );
$oh->set( 'a' => 2 ); # $oh->[0]->{'a'} = 2
say $oh->get( 'a' ); # 2
# say Dumper($oh);
=pod
$VAR1 = bless( [
{ 'a' => 2 },
[ 'a' ],
undef, 0, 0
], 'Hash::Ordered' );
=cut
say encode_utf8( '# key 存在チェック' );
say $oh->exists( 'a' ); # 1
say $oh->exists( 'b' ); # '' (zero-length)
say encode_utf8( '# key/value 削除' );
my $val = $oh->delete( 'a' );
say $val; # 2
say Dumper($oh);
=pod
$VAR1 = bless( [
{},
[],
undef,
0,
0
], 'Hash::Ordered' );
=cut
say encode_utf8( '# 複数の key/value の組を push' );
$oh->push( 'a' => 'あ', 'b' => 'い');
$oh->push(qw/c う d え/);
say Dumper($oh);
=pod
$VAR1 = bless( [
{
'a' => "\x{3042}", # あ
'c' => "\x{3046}", # う
'd' => "\x{3048}", # え
'b' => "\x{3044}" # い
},
[
'a',
'b',
'c',
'd'
],
undef,
0,
0
], 'Hash::Ordered' );
=cut
say encode_utf8( '# 複数の key/value の組を unshift' );
$oh->unshift( qw/C ぅ D ぇ/ );
$oh->unshift( 'A' => 'ぁ', 'B' => 'ぃ' );
say Dumper($oh);
=pod
$VAR1 = bless( [
{
'D' => "\x{3047}",
'd' => "\x{3048}",
'A' => "\x{3041}",
'a' => "\x{3042}",
'B' => "\x{3043}",
'b' => "\x{3044}",
'C' => "\x{3045}",
'c' => "\x{3046}"
},
[
'A',
'B',
'C',
'D',
'a',
'b',
'c',
'd'
],
undef,
0,
0
], 'Hash::Ordered' );
=cut
say encode_utf8( '# キーのみ, 値のみ, 両方 の配列取得' );
my @keys = $oh->keys();
say encode_utf8( join ', ', @keys );
my @vals = $oh->values();
say encode_utf8( join ', ', @vals );
my @keyvals = $oh->as_list();
say encode_utf8( join ', ', @keyvals );
=pod
A, B, C, D, a, b, c, d
ぁ, ぃ, ぅ, ぇ, あ, い, う, え
A, ぁ, B, ぃ, C, ぅ, D, ぇ, a, あ, b, い, c, う, d, え
=cut
say encode_utf8( '# key/value の組を pop/shift' );
my ($key, $value) = $oh->pop();
say encode_utf8( sprintf "poped: key='%s', value='%s'", $key, $value);
($key, $value) = $oh->shift();
say encode_utf8( sprintf "shifted: key='%s', value='%s'", $key, $value);
say encode_utf8( sprintf "after: %s", join( ', ', $oh->as_list()) );
say encode_utf8( '# イテレータ' );
my $iter = $oh->iterator();
my $n = 0;
while( my ( $k, $v ) = $iter->() ) {
say encode_utf8( sprintf "[%d] key='%s' value='%s'", $n++, $k, $v);
}
# TODO: clone から
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment