到位排序的Perl数组? [英] Sort Perl array in place?

查看:157
本文介绍了到位排序的Perl数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数组引用( $间隔的称呼),我想值此数组中排序。这是可能的,有可能是在数组中值的数量巨大,所以我会preFER不要复制值。我目前的做法是这样的。

I have a reference to an array (called $intervals) and I would like to sort the values in this array. It's possible that there could be a huge number of values in the array, so I would prefer not to copy the values. My current approach is this.

sub by_position
{
  $a->start <=> $b->start ||
  $a->end   <=> $b->end
}
my @sorted_intervals = sort by_position (@$intervals);

不过,如果我理解正确的Perl这确实是所有的值复制数组中为止。是对的吗?如果是这样,是有办法,我可以做一个就地排序的数组(使用到数组的引用)?

However, if I understand Perl correctly this will indeed copy all of the values in the array. Is that right? If so, is there a way that I can do an in-place sort of an array (using a reference to that array)?

推荐答案

Perl的允许阵列就地用这个成语来排序 @arr =排序@arr 。相反,赋值运算符的正常行为,不会生成副本在这种情况下进行。然而,该优化被限制为正常的数组变量;它不会与数组引用工作:

Perl allows arrays to be sorted in-place with the idiom @arr = sort @arr. Contrary to the normal behavior of the assignment operator, no copies will be made in this case. However, this optimization is limited to normal array variables; it won't work with array references:

让我们来看看引擎盖下使用 -MO =简明选项。首先,我们做正常的就地分拣,看看我们所期待的:

Let's look under the hood by using the -MO=Concise option. First, we do normal in-place sorting to see what we'd expect:

$ perl -E'say $^V'
v5.18.2
$ perl -MO=Concise -e'my @arr; @arr = sort @arr'
8  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -e:1) v:{ ->3
3     <0> padav[@arr:1,2] vM/LVINTRO ->4
4     <;> nextstate(main 2 -e:1) v:{ ->5
-     <1> ex-aassign vKS/64 ->8
-        <1> ex-list lK ->-
5           <0> pushmark s ->6
7           <@> sort lK/INPLACE ->8
6              <0> padrange[@arr:1,2] l/1 ->7
-              <0> padav[@arr:1,2] lRM* ->7
-        <1> ex-list lK ->-
-           <0> ex-pushmark s ->-
-           <0> ex-padav lRM* ->-
-e syntax OK

有趣的:&LT; @&GT;排序LK / INPLACE - →8 ,这似乎在地方进行排序。现在让我们做引用同样的事情:

Interesting: <@> sort lK/INPLACE ->8, which seems to sort in place. Now let's do the same thing with references:

$ perl -MO=Concise -e'my $ref; @$ref = sort @$ref'
e  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -e:1) v:{ ->3
3     <0> padsv[$ref:1,2] vM/LVINTRO ->4
4     <;> nextstate(main 2 -e:1) v:{ ->5
d     <2> aassign[t4] vKS/COMMON ->e
-        <1> ex-list lK ->a
5           <0> pushmark s ->6
9           <@> sort lK ->a
6              <0> pushmark s ->7
8              <1> rv2av[t3] lK/1 ->9
7                 <0> padsv[$ref:1,2] s ->8
-        <1> ex-list lK ->d
a           <0> pushmark s ->b
c           <1> rv2av[t2] lKRM*/1 ->d
b              <0> padsv[$ref:1,2] sM/DREFAV ->c
-e syntax OK

我没有看到一个就地标志&LT; @&GT;排序LK - &gt;将。所以优化似乎只使用相同的变量时,使用相同的数组时不工作。但是,这意味着我们可以到位数组引用如果我们别名的数组变量被一些标引用的数组(使用数据进行排序::别名):

I do not see an inplace flag in <@> sort lK ->a. So the optimization only seems to work when using the same variable, not when using the same array. But this means we can sort array references in place if we alias an array variable to the array referenced by some scalar (using Data::Alias):

perl -MData::Alias -MO=Concise -e'my $ref; alias my @arr = @$ref; @arr = sort @arr'
e  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -e:1) v:{ ->3
3     <0> padsv[$ref:1,3] vM/LVINTRO ->4
4     <;> nextstate(main 2 -e:1) v:{ ->5
-     <1> entersub vKS/INARGS ->a
         ...
a     <;> nextstate(main 3 -e:1) v:{ ->b
-     <1> ex-aassign vKS/64 ->e
-        <1> ex-list lK ->-
b           <0> pushmark s ->c
d           <@> sort lK/INPLACE ->e
c              <0> padrange[@arr:2,3] l/1 ->d
-              <0> padav[@arr:2,3] lRM* ->d
-        <1> ex-list lK ->-
-           <0> ex-pushmark s ->-
-           <0> ex-padav lRM* ->-
-e syntax OK

...和就地标志有再次&LT; @&GT;排序LK / INPLACE - &GT; e : - )

这意味着,埃里克·斯特罗姆的回答是不正确。

这篇关于到位排序的Perl数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆