2010-06-10 18 views
6

Hãy nói rằng tôi có danh sách này:Làm thế nào tôi cũng có thể nhận được chỉ mục của phần tử khi tôi grep thông qua một mảng?

my @list = qw(one two three four five); 

và tôi muốn lấy tất cả các yếu tố có chứa o. Tôi muốn có điều này:

my @containing_o = grep { /o/ } @list; 

Nhưng những gì tôi sẽ phải làm cũng để nhận được một chỉ mục, hoặc để có thể truy cập vào chỉ mục trong cơ thể grep 's?

Trả lời

15

 

my @index_containing_o = grep { $list[$_] =~ /o/ } 0..$#list; # ==> (0,1,3) 

my %hash_of_containing_o = map { $list[$_]=~/o/?($list[$_]=>$_):() } 0..$#list 
      # ==> ('one' => 0, 'two' => 1, 'four' => 3) 
+0

Suy nghĩ tuyệt vời :)! – Geo

10

Hãy xem List::MoreUtils. Bạn có thể làm được nhiều việc có ích với mảng mà không cần phải cuộn phiên bản của riêng mình, cộng với đó là nhanh hơn (vì nó thực hiện trong C/XS):

use List::MoreUtils qw(first_index indexes); 

my $index_of_matching_element = first_index { /o/ } @list; 

Đối với tất cả các chỉ số phù hợp, và sau đó phần tử tương ứng của họ, bạn có thể làm:

my @matching_indices = indexes { /o/ } @list; 
my @matching_values = @list[@matching_indices]; 

hoặc chỉ:

my @matching_values = grep { /o/ } @list; 
+0

Liệu điều này không chỉ trả lại chỉ mục của phần tử đầu tiên? – Geo

+0

Đúng. Tôi nghĩ Ether có nghĩa là sử dụng chức năng 'indexes' sẽ cung cấp danh sách tất cả các chỉ mục trả về true cho khối. – friedo

+0

Có, tôi đã làm ... Tôi nhấn gửi quá sớm trước khi kiểm tra công việc của tôi. cảm ơn :) – Ether

2

này populates 2 mảng với những gì bạn muốn, lặp qua mảng đầu vào một lần:

use strict; 
use warnings; 
my @list = qw(one two three four five); 
my @containing_o; 
my @indexes_o; 
for (0 .. $#list) { 
    if ($list[$_] =~ /o/) { 
     push @containing_o, $list[$_]; 
     push @indexes_o , $_; 
    } 
} 
Các vấn đề liên quan