2010-07-08 3 views
6

N의 배열로 구문 분석하기 위해 split을 사용하는 CSV 파일이 있습니다. 여기에서 N3의 배수입니다.Perl에서 배열의 여러 요소를 반복 할 수 있습니까?

내가 파이썬이

foreach my ($a, $b, $c) (@d) {} 

비슷한 할 수있는 방법이 있나요?

+7

을'$ a를 '와'$ b'를 사용합니다. 그것들은'sort '와 함께 사용하기 위해 특별히 패키지화 된 범위 변수입니다. –

+0

그래도 할 수 있으면 멋질 것입니다. –

+0

당신이 정렬 밖이라면 괜찮습니다. 그러나 그것이 한 줄짜리라면 재사용 할 것입니다. 아마도 나중에 일종의 조심스럽게 조심해야합니다. :-) – eruciform

답변

12

당신은 List::MoreUtils::natatime를 사용할 수있는 문서에서 :.

my @x = ('a' .. 'g'); 
my $it = natatime 3, @x; 
while (my @vals = $it->()) { 
    print "@vals\n"; 
} 

natatime는 XS에서 구현

당신이 효율성을 선호한다, 그래서 그냥 설명을 위해, 여기에서이 세 가지를 구현하는 방법이다. 펄 요소의 반복자 발생기 :

#!/usr/bin/perl 

use strict; use warnings; 

my @v = ('a' .. 'z'); 

my $it = make_3it(\@v); 

while (my @tuple = $it->()) { 
    print "@tuple\n"; 
} 

sub make_3it { 
    my ($arr) = @_; 
    { 
     my $lower = 0; 
     return sub { 
      return unless $lower < @$arr; 
      my $upper = $lower + 2; 
      @$arr > $upper or $upper = $#$arr; 
      my @ret = @$arr[$lower .. $upper]; 
      $lower = $upper + 1; 
      return @ret; 
     } 
    } 
} 
+0

* n * 한 번에 - 나는 그것을 좋아한다 :-) – Mike

+0

heh funny, 그것에 대해 몰랐다. 아마도 스플 라이스 (splice) 주변에 한 줄의 폐쇄가있을 것입니다. :-) – eruciform

+1

@eruciform : 로직에서는 그렇습니다. 그러나 List :: Util 및 List :: MoreUtils의 함수는 최대 속도를 위해 XS로 작성되었습니다.방대한 양의 데이터를 파싱 할 때 내장 함수를 사용하는 것보다 필요한 함수를 사용하는 것이 좋습니다. – Ether

4
@z=(1,2,3,4,5,6,7,8,9,0); 

for(@tuple=splice(@z,0,3); @tuple; @tuple=splice(@z,0,3)) 
{ 
    print "$tuple[0] $tuple[1] $tuple[2]\n"; 
} 

는 생산 : 쉽게

1 2 3 
4 5 6 
7 8 9 
0 
+1

이것은'@ z' 배열을 파괴하고 while 루프로서 더 잘 작성되었습니다. –

+0

@eric : true. 이것은 빠른 해결책입니다. – eruciform

1

하지 않습니다. 당신은 배열 참조로 배열에 요소를 밀어, @d 세 가지 요소 튜플의 배열을 더 나을 것 :

foreach my $line (<>) 
    push @d, [ split /,/, $line ]; 

(당신이 정말로 CPAN에서 CSV 모듈 중 하나를 사용한다고 그 제외 .

+0

thx, 그것은 빠른 내부 해킹을 위해, 그것은 매우 어려울 것이라고 생각하지 않았다. – Timmy

14

나는 CPAN 내 모듈 List::Gen에서이 문제를 해결.

use List::Gen qw/by/; 

for my $items (by 3 => @list) { 

    # do something with @$items which will contain 3 element slices of @list 

    # unlike natatime or other common solutions, the elements in @$items are 
    # aliased to @list, just like in a normal foreach loop 

} 

당신은 또한 by을 구현하기 위해 List::Gen 사용하는 mapn 기능을 가져올 수 :

use List::Gen qw/mapn/; 

mapn { 

    # do something with the slices in @_ 

} 3 => @list; 
+0

그들은 실제로 "내"를 위해 별칭이 지정되어 있습니까? 또는 "for"루프에 그냥 있습니까? "my"는 사본을 만들어야합니다. "by"가이 문제를 해결합니까? – eruciform

+2

Perl foreach 루프의 'my' 변수는 결코 사본이 아니며 항상 별칭입니다. 어휘 적으로 범위가 지정된 별칭이지만 별칭은 적습니다. –

+3

내가 말할 수있는 것은 * 아주 멋지다! * –

4
my @list = (qw(one two three four five six seven eight nine)); 

while (my ($m, $n, $o) = splice (@list,0,3)) { 
    print "$m $n $o\n"; 
} 

이 출력 : 사용하지 마십시오

one two three 
four five six 
seven eight nine 
관련 문제