Ranvis Script

Ranvis Script > Perl/PHP > ソート

文字列・数値

文字列配列のソート/降順ソート

sort()は引き数として渡した配列を直接ソートする。また降順にするにはrsort()を使う。

# Perl
@outArray = sort @inArray;
@outArray = sort {$b cmp $a} @inArray;
// PHP
$success = sort($inoutArray);
$success = rsort($inoutArray);

数列のソート

文字列の場合と同じようにすればよい。

# Perl
@outArray = sort {$a <=> $b} @inArray;
@outArray = sort {$b <=> $a} @inArray;

数の混在するソート

そのままsort()すると文字列と数が別々にソートされてしまうのでSORT_STRINGを指定する。

# Perl
@outArray = sort @inArray;
// PHP
$success = sort($inoutArray, SORT_STRING);

独自の比較関数によるソート

Perlでは$a, $bが比較内容を保持する変数として予約されているが、(当然)PHPにはこの仕様はない。

# Perl
@outArray = sort userfunc @inArray;

sub userfunc {
    return $a->{'year'} <=> $b->{'year'} || $a->{'name'} cmp $b->{'name'};
}
// PHP
$success = usort($inoutArray, 'userfunc');

function userfunc($a, $b)
{
    if (($result = ($a['year'] - $b['year'])) == 0) {
        $result = strcmp($a['name'], $b['name']);
    }
    return $result;
}
# Perl
@outArray = sort {
    $a->{'year'} <=> $b->{'year'} || $a->{'name'} cmp $b->{'name'}
} @inArray;
// PHP
$success = usort($inoutArray, function ($a, $b) { // PHP 5.3+
    return
        ($a['year'] <=> $b['year']) // PHP 7.0+
            ?: // PHP 5.3+
        strcmp($a['name'], $b['name']);
});

数字の混在する文字列配列のソート

PHPには文字列中の、桁数の揃っていない数字を並び替える時に使えるnatural orderingという方式のnatsort()natcasesort()がある。

# Perl
my @outArray = sort strnatcmp @inArray;

sub strnatcmp {
    my $max = sub { $_[0] > $_[1] ? $_[0] : $_[1] };
    my @a = split(/(\d+)/a, $a);
    my @b = split(/(\d+)/a, $b);
    my ($an, $bn);
    for (0..$max->($#a, $#b)) {
        my $l = $max->(length($a[$_]), length($b[$_]));
        $an .= $a[$_] =~ /^\d/a ? sprintf('%0*d', $l, $a[$_]) : $a[$_];
        $bn .= $b[$_] =~ /^\d/a ? sprintf('%0*d', $l, $b[$_]) : $b[$_];
    }
    return $an cmp $bn;
}
// PHP
$success = natsort($inoutArray);

連想配列

すでに述べた通りPHPではPerlと異なり配列と連想配列の区別がない。つまり連想配列にもインデックスがある。

連想キーをソートする

連想配列をキーでソートするにはksort()krsort()を使う。

# Perl
foreach $key (sort keys %hash) {
    ...
}
// PHP
ksort($hash);
foreach ($hash as $key => $value) {
    ...
}

連想キーを独自の比較関数でソートする

usort()の連想キー版であるuksort()を使う。

連想配列の値をソートする

sort()は連想キーを消してしまうので使えない。値でソートするにはasort()arsort()を使う。

# Perl
foreach $key (sort { $hash{$a} cmp $hash{$b} } keys %hash) {
    ...
}
// PHP
asort($hash);
foreach ($hash as $key => $value) {
    ...
}