4

反復処理中に配列で許可される操作は何ですか? イテレータを混乱させることなく、要素をシフト/シフト解除、ポップ/プッシュ、削除することは可能ですか?

ハッシュからキーと値のペアを追加/削除することは違いますか?

ご協力ありがとうございました。

4

2 に答える 2

5

既存の要素に割り当てることはできますが、それらを追加または削除しないでください。したがって、シフト、シフト解除、ポップ、プッシュ、スプライスはありません。 パールシン

LIST のいずれかの部分が配列である場合、たとえば splice を使用してループ本体内で要素を追加または削除すると、foreach は非常に混乱します。だから、それをしないでください。

を使用してハッシュを反復処理する場合はeach、現在の要素を削除することが明示的に許可されている場合を除いて、要素の追加または削除も避ける必要があります。 それぞれ:

反復中にハッシュの要素を追加または削除した場合、反復子への影響は規定されていません。たとえば、エントリがスキップされたり、複製されたりする可能性があるため、そうしないでください。例外: each() によって最後に返された項目を削除しても常に安全であるため、次のコードは適切に機能します。

しかし、それが言うように、起こりうる最悪の事態は、エントリがスキップされたり複製されたりすることです。一方、ループしている配列を変更すると、セグメンテーション違反が発生する可能性があります。

于 2014-10-23T07:55:13.417 に答える
2

ysth がすでに指摘しているように、要素を直接反復しながら配列を変更しようとするのは賢明ではありません。

ただし、要素の値に応じて配列を変更したい場合は、逆のインデックス順で行うのがコツです。

たとえば、数値の配列があるとします。配列を変更して、4 の倍数の後に文字列が挿入され、5 の倍数が削除されるようにします。私は以下を使用してそれを達成します:

use strict;
use warnings;

my @array = ( 1 .. 20 );

for my $i ( reverse 0 .. $#array ) {
    # Insert after multiples of 4
    if ( ( $array[$i] % 4 ) == 0 ) {
        splice @array, $i + 1, 0, "insert";
    }

    # Remove multiples of 5
    if ( ( $array[$i] % 5 ) == 0 ) {
        splice @array, $i, 1;
    }
}

use Data::Dump;
dd @array;

出力:

(
  1 .. 4,
  "insert",
  6,
  7,
  8,
  "insert",
  9,
  11,
  12,
  "insert",
  13,
  14,
  16,
  "insert",
  17,
  18,
  19,
  "insert",
)

mapまたは、配列を変換する場合は、次のように使用することもできます。

my @newarray = map {
    (   ( ($_) x !!( $_ % 5 ) ),         # Remove multiples of 5
        ( ('insert') x !( $_ % 4 ) ),    # Insert After multiples of 4
        )
} ( 1 .. 20 );

use Data::Dump;
dd @newarray;
于 2014-10-23T22:32:44.273 に答える