Как я уменьшаю массив в Perl?

Вы можете использовать его для вызова метода суперкласса (например, когда вы переопределяете такой метод, super.foo () и т. д.) - это позволит вам сохранить эту функциональность и добавить к ней все, что у вас есть в методе переопределения.

10
задан brian d foy 8 October 2008 в 07:27
поделиться

8 ответов

Я не знаю о присвоении $#ARRAY быть удержавшим от использования; perldoc perldata от 5.10.0, конечно, ничего не говорит об этом. Это - самый быстрый способ усечь массив.

Если Вы хотите что-то немного более читаемое, использовать splice:

splice @ARRAY, 43;

(Примечание 43 вместо 42 - $#ARRAY получает Вас последний индекс массива, тогда как splice прикрепляет длину массива вместо этого).

Что касается работы над массивами массивов, я предполагаю, что Вы имеете в виду способность усечь вложенный массив через ссылку? В этом случае Вы хотите:

$#{$ARRAY->[7]} = 42;

или

splice @{$ARRAY->[7]}, 43;
16
ответ дан 3 December 2019 в 13:51
поделиться

$# переменная удерживается от использования, но $#array функция не.

Использовать $#array синтаксис по произвольному выражению, которое приводит к ссылке на массив, сделать $#{ EXPR }.

Посмотрите неоценимое: http://perlmonks.org/?node=References+quick+reference

7
ответ дан 3 December 2019 в 13:51
поделиться

Ваши опции почти безграничны (я обрисовал в общих чертах пять подходов здесь), но Вашей стратегией продиктуют точно, каковы Ваши определенные потребности и цели. (все примеры преобразуют @array, чтобы иметь не больше, чем элементы $N),


[Править]

Как другие указали, путь, предложенный в исходном вопросе, на самом деле не удерживается от использования, и он обеспечивает самое быстрое, самое краткое, но не обязательно самое читаемое решение. Это также имеет побочный эффект расширения массива меньше, чем элементы $N с пустыми элементами:

$#array = $N-1;

Наименьшее количество кода:

#best for trimming down large arrays into small arrays
@array = $array[0..($N-1)];

Самый эффективный для обрезки небольшого числа прочь большого массива:

#This is a little less expensive and clearer
splice(@array, $n, @#array);

Нежелательный почти во всех случаях, если Вы действительно не любите, удаляет ():

#this is the worst solution yet because it requires resizing after the delete
while($N-1 < $#array)
{
   delete(array[$i]);
}

Полезный, если Вам нужен остаток от списка в обратном порядке:

#this is better than deleting because there is no resize
while($N-1 < $#array)
{
    pop @array;
    #or, "push $array2, pop @array;" for the reverse order remainder
}

Полезный для того, чтобы сэкономить время в длительный период:

#don't put more values into the array than you actually want
10
ответ дан 3 December 2019 в 13:51
поделиться

$ # {$ARRAY [$i]} = 42;

0
ответ дан 3 December 2019 в 13:51
поделиться

Вы могли сделать

splice @array, $length;
#or
splice @{$arrays[$i]}, $length;
0
ответ дан 3 December 2019 в 13:51
поделиться

Вы по существу дали канонический ответ сами. Вы сокращаете массив путем установки последнего индекса:

$#Array = 42

$ нотация #Foo для обозначения последнего индекса в массиве абсолютно не удерживается от использования. Точно так же присвоение ему не будет удерживаться от использования также. Заключение в кавычки perldata документации:

Длина массива является скалярной величиной. Можно найти длину массива @days путем оценки $ #days, как в csh. Однако это не длина массива; это - нижний индекс последнего элемента, который является другим значением, так как обычно существует 0th элемент. Присвоение $ #days на самом деле изменяет длину массива. При сокращении массива этот путь уничтожает прошедшие значения. Удлинение массива, который был ранее сокращен, не восстанавливает значения, которые были в тех элементах. (Это раньше делало так в Perl 4, но мы должны были повредить это, чтобы удостовериться, что деструкторы назвали при ожидании.)

5
ответ дан 3 December 2019 в 13:51
поделиться
  • $ #array является последним индексом массива.
  • $ # $array был бы последним индексом массива, на который указывает $array.
  • $ # $array [$i] означает, что Вы пытаетесь индексировать скаляр - не может быть сделан. $ # {$array [3]} правильно разрешает индексирование основного массива, прежде чем мы попытаемся сослаться на последний индекс.
  • Используемый один

    $ # {$array [3]} = 9;

    присваивает длину 9 к автооживляемому массиву на уровне $array [3].

  • Когда в сомнении, используйте Данные:: Самосвал:

    use Data::Dumper;
    $#{$array[3]} = 5;
    $#array       = 10;
    print Dumper( \@array, $array ), "\n";
    
2
ответ дан 3 December 2019 в 13:51
поделиться

Существует два способа интерпретировать вопрос.

  • Как уменьшить длину массива?
  • Как уменьшить объем памяти, использованный массивом?

Большинство ответов до сих пор фокусируется на первом. По моему мнению, лучший ответ на это является функцией соединения встык. Например, для удаления 10 элементов из конца:

splice @array, -10;

Однако из-за того, как Perl управляет памятью для массивов, единственный способ гарантировать, что массив берет меньше памяти, состоит в том, чтобы скопировать его в новый массив (и позволить памяти старого массива быть исправленной). Для этого я был бы склонен думать об использовании операции части. Например, для удаления 10 элементов:

@new = @old[ 0 .. $#old - 10 ]

Вот сравнение разных подходов для 500 массивов элемента (использующий 2 104 байта):

  original: length  500 => size 2104
     pound: length  490 => size 2208
    splice: length  490 => size 2104
    delete: length  490 => size 2104
     slice: length  490 => size 2064

Вы видите, что только операция части (скопированный в новый массив) имеет меньший размер, чем оригинал.

Вот код, который я использовал для этого анализа:

use strict;
use warnings;
use 5.010;
use Devel::Size qw/size/;

my @original = (1 .. 500);
show( 'original', \@original );

my @pound = @original;
$#pound = $#pound - 10;
show( 'pound', \@pound );

my @splice = @original;
splice(@splice,-10);
show( 'splice', \@splice);

my @delete = @original;
delete @delete[ -10 .. -1 ];
show( 'delete', \@delete );

my @slice = @original[0 .. $#original - 10];
show( 'slice', \@slice);

sub show {
    my ($name, $ref) = @_;
    printf( "%10s: length %4d => size %d\n", $name, scalar @$ref, size($ref));
}
0
ответ дан 3 December 2019 в 13:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: