将Perl推入已排序数组

7
考虑下面的数据块,我应该如何通过第三个字段来保持数组排序,并继续添加项目?
$VAR1 = [
          '1111',
          'http://...',
           3       #this is one of the 3rd field mentioned above
        ];
$VARN = [
           '5555',
           'http://...',
            0
        ];

我的代码看起来像这样:
my @curItem = ($item->{id}, $item->{href}, getTotal( $item->{id}) );
push @items, \@curItem;

我找到了一个类似于我所需的模块,在这里

非常感谢任何帮助。

3个回答

8
您可以使用该模块,只需提供排序方式即可: tie @a, "Tie::Array::Sorted", sub { $_[0]->[2] <=> $_[1]->[2] }; (或类似的方式...我需要检查一下。基本上,您需要根据传递进来的数组引用元素进行排序) 编辑:是的,这可以适用于您的数据。我刚刚检查了一下。
use Tie::Array::Sorted;

tie @a, "Tie::Array::Sorted", sub { $_[0]->[2] <=> $_[1]->[2] };

push @a, [ "1111", "http:// ...", 3];
push @a, [ "5555", "http:// ...", 0];

foreach $ref (@a)
{
    print $ref . "\n";
    print "@$ref \n";
}

输出:

ARRAY(0x9130888)
5555 http:// ... 0
ARRAY(0x90dd818)
1111 http:// ... 3

3

嗯,push操作将无论如何都会将项目附加到列表末尾。这是一个堆栈操作。我认为你最好使用不同的数据结构,例如哈希表,然后仅在必要时按键或值进行排序。如果没有更多关于你正在编写的内容的详细信息,很难说。

否则,您需要编写一个子例程,该子例程搜索最佳插入位置的列表,然后使用splice将项目注入到正确的位置。这听起来更像是您想要做的事情,但我不确定它是否特别有效,因为您每次想添加一个项目时都必须搜索插入点,同时保持排序顺序。


同意。这个问题要求的是逻辑上不一致的东西;你不能既保持一个特定排序顺序的数组,又使用 push 来添加元素,因为 push 根据它们被添加的顺序存储项目,而不是根据它们的内容。至于在插入时进行排序的效率,对数据进行插入排序是最快的排序方式之一,而且避免了每次访问数据时重新排序的需要,因此在绝大多数情况下,这将是一种胜利。 - Dave Sherohman

1
如果您要将多个数组引用添加到@items中,请先添加引用,然后使用Schwartzian Transform执行单个排序操作:
@items = map $_->[1], sort { $a->[0] <=> $b->[0] } map { [ $_->[2], $_ ] } @items;

Randal 写了一篇关于这个的专栏文章:http://www.stonehenge.com/merlyn/UnixReview/col64.html

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接