4

現在、私は得点されたサッカーのゴールに関する情報を含む 2 次元配列を使用しています。最初の配列の各項目は、目標に関するさまざまな情報を含む配列です。この配列の 2 番目の項目は、得点された分 (1 ~ 90) です。これは、それらが何をスコアラインにしたかを判断できるように、それらを順番に並べたいためです。その「分」の値を使用して、次のように並べ替えています。

@allinfogoals = sort { $a->[1] <=> $b->[1] } @allinfogoals;

延長戦で得点されたゴールに遭遇するまで、これはうまく機能します。これらの分は、「90+2」または「45+3」のように表示されます。これで、それらを一緒に追加できますが、順序が正しくない可能性があります. この場合、ハーフタイム直前に得点されたゴールは、後半開始直後に得点されたゴールの後に得点されたものとして保存される可能性があります。

そこで、この 90+x 形式の分を見つけて、「+」で分割しています。私は配列に分を定期的に保存する最初の値を保存していますが、配列の最後 (12 番目の項目) に別の値を追加し、その 2 番目の部分 (余分な時間に分) を入れています。通常の目標の場合は 0 です。

上記の並べ替えを修正してこれを補正し、適切な順序を維持するにはどうすればよいですか?

4

3 に答える 3

5

最初に 1 つのキーでソートし、そのキーが同じ場合は 2 番目のキーでソートしたいようです。

たとえば、45+2 を 45 と 46 の間でソートしたいとします。

これは、次を使用するだけで実行できます。

@ls = sort { $a->[0] <=> $b->[0] || $a->[1] <=> $b->[1] } @ls

最初のキーが同じ場合にのみ、2 番目のキーが参照されます。

完全な例を次に示します。

my @allinfogoals=(
                  [ 46, 0 ],
                  [ 45, 2 ],
                  [ 45, 0 ],
                  [ 33, 0 ],
                  [ 91, 0 ],
                  [ 90, 2 ],
                 );

@allinfogoals=sort { $a->[0] <=> $b->[0] || $a->[1] <=> $b->[1] } @allinfogoals;

use Data::Dump; dd \@allinfogoals;

出力は次のとおりです。

[[33, 0], [45, 0], [45, 2], [46, 0], [90, 2], [91, 0]]
于 2012-12-26T03:14:39.833 に答える
2

これは「ブルート フォース」ソリューションであり、巧妙さはあまりありませんが、機能します。2 次元のデータ構造は改造しないと動きませんが、一方で、データ構造がどのように見えるかはわかりません。

use strict;
use warnings;
use feature 'say';

my @data = qw(22 45+3 45 46 90 90+3);

my @sorted = map $_->[2],               # turn back to org string
        sort {
            $a->[0] <=> $b->[0] ||      # default sort by period number
            $a->[1] <=> $b->[1]         # or by minute
        } map mysort($_), @data;        # map all minutes to 3-element array

say for @sorted;

sub mysort {
    my $time = shift;
    if ($time =~ /45\+(\d+)/) {
        return [1, 45+$1, $time];
    } elsif ($time =~ /90\+(\d+)/) {
        return [2, 90+$1, $time];
    } else {
        my $period = ($time <= 45 ? 1 : 2);
        return [$period, $time, $time]
    }
}

これは、シュワルツ変換を使用して、各分のエントリを、期間番号、その期間内の分、および元の文字列で構成される 3 つの要素の配列に変換します。このスクリプトの出力は次のとおりです。

22
45
45+3
46
90
90+3
于 2012-12-26T03:50:35.470 に答える
0

この特定のケースでは、あなたが説明したように、残業時間を10分の1に変換して数値で注文することもできます(誰かが答えたが、再び削除されたようです):

my @allinfogoals=qw(46 45+2 45 33 91 90+2);

@allinfogoals=map { s/[.]/+/; $_ } sort { $a <=> $b } map { s/[+]/./; $_ } @allinfogoals;

use Data::Dump; dd \@allinfogoals;

...そして、元に戻します。出力:

[33, 45, "45+2", 46, "90+2", 91]
于 2012-12-26T03:25:42.187 に答える