6

タブ区切りのレコードの4番目、5番目、および7番目の要素(たとえば)のみを抽出したい場合は、次のようにすることができます。

my @f = (split(/\t/, $_, -1))[3, 4, 6];

しかし、4番目の要素と、7番目の要素から配列の最後までのすべての要素で構成される「テールスライス」が必要な場合はどうなりますか?これを1行で行う方法がわかりません。私ができる最善のことはこれです:

my @f = split(/\t/, $_, -1);
@f = @f[3, 6..$#f];

この操作を2行で行う唯一の理由は$#f、2行目で指定できるようにするためですが、これには、タスクに固有のものよりも高度な特異性が伴います。タスクは、によって返される値に含まれる要素の数を実際にはにしませんsplit。「7番目以降の要素から利用できるものすべて」のようなものを指定できると便利です...これが「テールスライス」の意味です。つまり、始点のみが指定され、終点のみが指定されるスライスです。暗黙的に残されます。

(この種の仕様はcut、Unixでのユーティリティの使用では一般的です。例:

... | cut -f 4,7-

)。

(split(...))上記のコードの最後の2行で達成されるのと同じ効果を1行で生成するために、部分式に直接適用できるいくつかの添え字式はありますか?

編集:明確にするために、私が避けようとしているのは$#ARRAY構造です。私はいつでも次のようなことができることを知っています

my @f = do { my @t = split(/\t/, $_, -1); @t[3, 6..$#t] };
4

1 に答える 1

8

リストスライスの括弧内の式は、0個以上のインデックスのリストを返す必要があります。したがって、リストが作成される前に、スライスされているリスト内のアイテムの数を知る必要があります。いいえ、リストスライスを使用して実行することはできません。

スタック上のリストにアクセスする最も直接的な方法は、を使用すること@_です。これにはサブ呼び出しが必要ですが、リストをスタックに残すための簡単なメカニズムが提供されます。

my @f = sub { @_[6..$#_] }->( split(/\t/, $_, -1) );

このソリューションでは、質問に追加してからのコードのように、配列を作成してその配列に値をコピーしないことに注意してください。

于 2013-01-09T01:03:59.580 に答える