开发者

Perl push into a sorted array

Consider the data block below, how can I maintain sorted the array by the 3rd field, and keep pushing items?

$VAR1 = [
          '1111',
开发者_如何学Go          'http://...',
           3       #this is one of the 3rd field mentioned above
        ];
$VARN = [
           '5555',
           'http://...',
            0
        ];

My code looks like:

my @curItem = ($item->{id}, $item->{href}, getTotal( $item->{id}) );
push @items, \@curItem;

I've found this module which is similar to what I need.

Any help appreciated.


You can use that module, you just need to supply the sort:

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

(Or something along those lines ... I'll have to check it. Basically, you need to sort based on the element of the array ref you're passing in)

Edit: Yup, this works for your data. Just checked it:

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";
}

Outputs:

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


Well, push is going to append the item to the end of the list no matter what. It's a stack operation. I'd say you'd probably be better off using a different data structure, such as a hash and then only sorting by key or value when necessary. Without more details of what you're trying to write, its hard to say.

Otherwise, you'll need to write a subroutine which searches the list for the best insert place then uses splice to inject the item into place. This sounds more like what you want to do, but I'm not sure its going to be particularly efficient, as you have to search the list for the insert point each time you want to add an item while maintaining a sorted order.


If you're adding more than one array reference to @items, add the references first, then use a Schwartzian Transform to perform a single sort operation:

@items = map $_->[1], sort { $a->[0] <=> $b->[0] } map { [ $_->[2], $_ ] } @items;

Randal wrote a column about this: http://www.stonehenge.com/merlyn/UnixReview/col64.html

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜