4

目前,我正在使用一个包含足球进球信息的二维数组。第一个数组中的每个项目都是一个数组,其中包含有关目标的不同信息。该数组中的第二项是分钟得分 (1-90),因为我希望它们按顺序排列,这样我就可以确定它们是什么构成了得分线。我正在使用该“分钟”值进行排序:

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

这很有效,直到我遇到加时赛进球。这些分钟显示为“90+2”或“45+3”。现在,我可以将它们加在一起,但这可能会使顺序不正确。在这种情况下,在半场结束前的进球可以存储为在下半场开始后不久进球后的进球。

所以,我正在寻找具有这种 90+x 格式的分钟并将它们拆分为“+”。我将第一个值存储在数组中定期存储分钟的位置,但我在数组的末尾添加了另一个值(第 12 项),我将第二部分(分钟到额外时间)放在那里。如果是常规目标,则为 0。

如何修改上面的排序以弥补这一点并使其保持正确的顺序?

4

3 回答 3

5

听起来您想先对一个键进行排序,如果该键相同,则您想对第二个键进行排序。

例如,您希望 45+2 在 45 和 46 之间排序。

您可以通过简单地使用来做到这一点:

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

只有当第一个密钥相同时,才会查询第二个密钥。

这是一个完整的例子:

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

这是一个“蛮力”解决方案,其中没有太多技巧,但可以完成工作。除非经过调整,否则它不适用于二维数据结构,但另一方面,我不知道您的数据结构是什么样的。

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]
    }
}

这使用Schwartzian 变换将每个分钟条目转换为一个三元素数组,由周期数、该周期内的分钟和原始字符串组成。这个脚本的输出是:

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

在这种特殊情况下,正如您所描述的那样,您还可以(正如有人回答但似乎再次删除)将您的加班时间转换为十分之一并按数字排序:

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 回答