Frage

Wie kann ich ein Array kürzer in Perl machen? Ich las einige Seiten anzeigt, dass ich zuweisen können:

$#ARRAY = 42;

Ich habe gelesen, dass die Verwendung von $ # veraltet. Ich brauche eine Lösung, die auch für eine Reihe von Feldern arbeiten. Dies hat nicht funktioniert:

$#$ARRAY[$i] = 42;
War es hilfreich?

Lösung

Ich bin mir nicht bewusst Zuordnung $#ARRAY veraltet ist; perldoc perldata von 5.10.0 sagt sicherlich nichts davon. Es ist der schnellste Weg, um ein Array zu kürzen.

Wenn Sie etwas wollen, ein wenig mehr lesbar ist, Gebrauch splice:

splice @ARRAY, 43;

. (Hinweis 43 statt 42 - $#ARRAY bekommt man den letzten Index des Arrays, während splice taks die Länge des Feldes statt)

Was auf Arrays von Arrays arbeiten, ich nehme an, Sie bedeuten in der Lage, eine verschachtelte Array über einen Verweis auf gestutzt? In diesem Fall möchten Sie:

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

oder

splice @{$ARRAY->[7]}, 43;

Andere Tipps

Ihre Möglichkeiten sind fast grenzenlos (Ich habe fünf Ansätze hier skizziert), aber Ihre Strategie sind durch genau das, was Ihre Bedürfnisse und Ziele vorgegeben werden. (Alle Beispiele werden @array konvertieren nicht mehr als $ N Elemente haben)


[EDIT]

Wie andere haben darauf hingewiesen, die Art und Weise in der ursprünglichen Frage vorgeschlagen ist eigentlich nicht veraltet, und es bietet die schnellsten, tersest, aber nicht unbedingt die am besten lesen Lösung. Es hat auch den Nebeneffekt, eine Reihe von weniger als $ N Elementen mit leeren Elementen erweitert :

$#array = $N-1;

Least Code:

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

Die meisten effizient für eine kleine Zahl aus einer großen Array Besatz:

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

Unerwünschte in fast allen Fällen, wenn Sie wirklich löschen lieben ():

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

Nützlich, wenn Sie den Rest der Liste in umgekehrter Reihenfolge müssen:

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

Nützlich für Zeit in langer Sicht zu speichern:

#don't put more values into the array than you actually want

Die $# Variable ist veraltet, aber die $#array Funktion nicht.

die $#array Syntax auf einem beliebigen Ausdruck zu verwenden, die eine Array-Referenz ergibt, tut $#{ EXPR }.

Siehe unschätzbarem Wert: http://perlmonks.org/?node=References+quick + Referenz

Sie gab im Wesentlichen der kanonischen selbst beantworten. Sie verkürzen ein Array von der letzten Indexeinstellung:

$#Array = 42

Die $ # Foo Notation für das Bezeichnen letzten Index im Array ist absolut nicht veraltet. In ähnlicher Weise wird auch nicht mehr unterstützt werden, um sie zuordnen. Unter Angabe der perldata Dokumentation:

  

Die Länge eines Arrays ist ein skalarer Wert. Sie können feststellen, die Länge   Array @days von $ # Tage Auswertung , wie in csh. Dies ist jedoch nicht der   Länge der Anordnung; es ist der Index des letzten Elements, das eine ist   anderer Wert, da es normalerweise ein 0-te Element. Zuordnung zu   $ # Tagen tatsächlich ändert die Länge des Arrays. Kürzen ein Array   auf diese Weise zerstört Werte dazwischen. eine Anordnung, die Verlängerung war   zuvor verkürzte Werte nicht wiederherstellen, die in das waren   Elemente. (Es wird verwendet, um in Perl 4 zu tun, aber wir hatten diese zu brechen   stellen Sie sicher, Destruktoren wurden aufgerufen, wenn erwartet wird.)

  • $ # Array ist der letzte Index des Arrays.
  • $ # $ array wäre der letzte Index eines Arrays deutete auf von $ array.
  • $ # $ array [$ i] bedeutet, Sie versuchen, einen skalaren zum Index - kann nicht durchgeführt werden. $ # {$ Array [3]} löst richtig die Subskribierung des Haupt Array, bevor wir versuchen, den letzten Index zu verweisen.
  • allein verwendet

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

    weist eine Länge von 9 zum autovivified Array bei $ array [3].

  • Im Zweifelsfall verwenden Data :: Dumper:

    use Data::Dumper;
    $#{$array[3]} = 5;
    $#array       = 10;
    print Dumper( \@array, $array ), "\n";
    

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

Sie können tun

splice @array, $length;
#or
splice @{$arrays[$i]}, $length;

Es gibt zwei Möglichkeiten, die Frage der Interpretation.

  • Wie wird die Länge des Arrays zu reduzieren?
  • Wie die Größe des Speichers durch die Anordnung verbraucht reduzieren?

Die meisten Antworten konzentrieren sich bisher auf dem ehemaligen. Aus meiner Sicht ist die beste Antwort auf, dass die Spleiß Funktion. Zum Beispiel 10 Elemente aus dem Ende zu entfernen:

splice @array, -10;

Da jedoch, wie Perl verwaltet Speicher für Arrays, die einzige Möglichkeit, sicherzustellen, dass ein Array weniger Speicher nimmt, ist es in ein neues Array zu kopieren (und lassen Sie die Erinnerung an die alte Anordnung zurückgewonnen werden). Dazu würde ich dazu neigen, über die Verwendung einer Scheibe Betrieb zu denken. Zum Beispiel 10 Elemente zu entfernen:

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

Hier ist ein Vergleich verschiedenen Ansätze für eine 500-Element-Array (mit 2104 Bytes):

  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

Sie können sehen, dass nur die Schichtbetrieb (kopiert in ein neues Array) eine kleinere Größe als das Original.

Hier ist der Code, den ich für diese Analyse verwendet:

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));
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top