0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

sortで複数条件を動的に処理するHow to

Last updated at Posted at 2025-04-22

perlのsort関数はかなり優秀で、下記の様に簡単に複数条件での並び替えが可能です。

@data = sort{ $a->{'key1'} <=> $b->{'key1'} || $a->{'str1'} cmp $b->{'str1'} } @data

が、しかし、置換(eオプション)の様に変数展開ができません。

my $e = "$a->{'key1'} <=> $b->{'key1'} || $a->{'str1'} cmp $b->{'str1'}";
@data = sort{ $e } @data
※みたいなことはできなかったです

evalを使用することで、課題クリアです!

my @data = (
    {   'name' => 'okuno',
        'key'  => '1',
        'key2' => '1',
    },
    {   'name' => 'yamada',
        'key'  => '2',
        'key2' => '2',
    },
    {   'name' => 'hanaoka',
        'key'  => '1',
        'key2' => '3',
    },
    {   'name' => 'suzuki',
        'key'  => '1',
        'key2' => '2',
    },
);

my @keys = ('key_number','key2_number'); # _numberで数値検索の判定
eval "\@data = sort { @{[&get_sort_formula(@keys)]} } \@data";

# @dataがsortされるので、後は必要な処理をどうぞ
exit;


# sort式リターン exp) $a->{'key'} <=> $b->{'key'} || $a->{'key2'} <=> $b->{'key2'}
sub get_sort_formula {
    my @keys = @_;
    
    my @sort;
    for my $order (@keys) {
        my ( $f, $a_d ) = split( / /, $order );
        my (@f) = split( /_/, $f ); # 数値 or 文字列判定 key_number

        if ($a_d) {
            if ( $f[1] ) {
                push( @sort, "\$b->{'$f[0]'} <=> \$a->{'$f[0]'}");
            }
            else {
                push( @sort, "\$b->{'$f[0]'} cmp \$a->{'$f[0]'}");
            }
        }
        else {
            if ( $f[1] ) {
                push( @sort, "\$a->{'$f[0]'} <=> \$b->{'$f[0]'}");
            }
            else {
                push( @sort, "\$a->{'$f[0]'} cmp \$b->{'$f[0]'}");
            }
        }
    }

    return join( ' || ', @sort);
}

eval実行式に文字列や変数だと実行されなかったり展開されたりするので、ダブルクォーテーションと¥を駆使することが重要です👍(evalを使用する時は変数エスケープなど慎重に)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?