2011-07-03 25 views
5

tôi có thể tạo ra một mảng với 'khe rỗng' trong đó:Làm cách nào để tạo một mảng ẩn danh ([]) với 'các vùng trống'?

$ perl -wde 1 
... 
    DB<1> $x[2] = 0 
    DB<2> x \@x 
0 ARRAY(0x103d5768) 
    0 empty slot 
    1 empty slot 
    2 0 

hoặc

DB<3> $#y = 4 
    DB<4> x \@y 
0 ARRAY(0x103d5718) 
    0 empty slot 
    1 empty slot 
    2 empty slot 
    3 empty slot 
    4 empty slot 

Xin lưu ý: đây không phải là giống như gán undef.

Nhưng làm cách nào để chỉ định điều đó cho mảng ẩn danh bằng cách sử dụng []?

này sẽ không làm việc:

DB<5> x [,,0] 
syntax error at (eval 27)[/usr/local/lib/perl5/5.10.0/perl5db.pl:638] line 2, near "[," 

Và điều này không quá, vì tôi chỉ nhận được giá trị giao:

DB<6> x []->[2] = 0 
0 0 

Bonus câu hỏi: làm thế nào tôi có thể kiểm tra một 'khe trống mảng' trong kịch bản Perl của tôi?

Bối cảnh: Trong các tập lệnh thử nghiệm của tôi, tôi muốn có thể so sánh chính xác nội dung mảng. Ví dụ tôi muốn phân biệt giữa 'không được chỉ định' và 'được gán với giá trị không xác định'.

Cảm ơn mọi thông tin chi tiết.

+1

Bạn có nghĩa là làm thế nào để làm một nhiệm vụ trực tiếp cho một mảng, sử dụng '[]' cho mảng ẩn danh, có các giá trị bên trong mảng trả về false khi được thử nghiệm với 'exist'? – TLP

+0

Có. Là lười biếng, nó sẽ là tốt đẹp để có thể xác định điều này trong một tuyên bố. Nếu không, tôi phải sử dụng 'undef' hoặc làm điều đó trong nhiều câu lệnh. – hexcoder

Trả lời

5
use feature qw/ say /; 
use strict; 
use warnings; 

my $aref; 

$#{$aref} = 4; 
$aref->[2] = undef; 
$aref->[3] = ''; 

foreach my $idx (0 .. $#{$aref}) { 
    say "Testing $idx."; 
    say "\t$idx exists." if exists $aref->[$idx]; 
    say "\t$idx defined." if defined $aref->[$idx]; 
} 

OUTPUT: 
Testing 0. 
Testing 1. 
Testing 2. 
    2 exists. 
Testing 3. 
    3 exists. 
    3 defined. 
Testing 4. 

Chúng tôi đã phân bổ trước năm vị trí trong mảng ẩn danh, @{$aref}. Chỉ số trên cùng là 4. Chúng tôi có thể tìm thấy chỉ số hàng đầu giống như cách chúng tôi tạo ra; bằng cách kiểm tra giá trị của $#{$aref}. Chúng ta có thể kiểm tra sự tồn tại. Chúng tôi biết mọi thứ giữa 04 đã được tạo. Nhưng Perl chỉ báo cáo "tồn tại" cho các phần tử mảng đã có một cái gì đó cụ thể được gán cho chúng (ngay cả khi nó là undef). Do đó, $aref->[2] được báo cáo là tồn tại, nhưng không được xác định. Chỉ để cho vui, chúng tôi đã chỉ định '' đến $aref->[3] để xem báo cáo thử nghiệm được xác định một lần.Nhưng câu chuyện ngắn là mặc dù mảng được mở rộng trước, chúng tôi vẫn có thể kiểm tra sự khác biệt giữa phần tử được khởi tạo với undef và phần tử là undef thông qua phần mở rộng trước mảng, bằng cách sử dụng 'exists'.

Tôi không thể nói rằng hành vi được ghi lại của tài liệu là exists. Vì vậy, không có gì đảm bảo nó sẽ không thay đổi vào một ngày nào đó. Nhưng nó hoạt động trên 5,8, 5,10, 5,12 và 5,14.

Vì vậy, tìm kiếm một cách đơn giản để tìm yếu tố nào được khởi tạo, được xác định, và đó không được, đây là một ví dụ:

use feature qw/ say /; 
use strict; 
use warnings; 

my $aref; 

$#{$aref} = 4; 
$aref->[2] = undef; 
$aref->[3] = ''; 

my @initialized = grep { exists $aref->[$_] } 0 .. $#{$aref}; 
my @defined = grep { defined $aref->[$_] } 0 .. $#{$aref}; 
my @uninitialized = grep { not exists $aref->[$_] } 0 .. $#{$aref}; 
my @init_undef = grep { exists $aref->[$_] and not defined $aref->[$_] } 0 .. $#{$aref}; 
say "Top index is $#{$aref}."; 
say "These elements are initialized: @initialized."; 
say "These elements are not initialized: @uninitialized."; 
say "These elements were initialized with 'undef': @init_undef."; 
say "These elements are defined: @defined." 
+0

Cảm ơn rất nhiều! Câu trả lời tuyệt vời cho câu hỏi thứ 2 của tôi! Trong khi đó, tôi phát hiện ra rằng 'xóa $ aref -> [2];' thay đổi trở lại 'không được khởi tạo' giống như nó làm cho các mục nhập băm. – hexcoder

+0

Tôi rất vui vì bạn thấy nó hữu ích. Nó luôn luôn vui vẻ làm việc thông qua các câu đố. – DavidO

-1

Bạn chỉ có thể thực hiện điều đó từ mã XS (xem ví dụ Devel::Peek). Một số, nhưng không phải tất cả, được phơi bày bởi các gói *::Util. (Tôi đã làm việc trên một debugging/truy tìm gói, vì vậy tôi biết thêm về điều này hơn bất cứ ai nên cần phải ....)

+0

Cảm ơn các con trỏ. Tôi sẽ có một cái nhìn. Quá xấu, không có cách nào Perl trực tiếp (và tôi nghĩ có nhiều cách để làm điều đó ;-). – hexcoder

+0

Tôi không thể tìm thấy bất cứ điều gì hữu ích trong * :: Util. Tôi hy vọng cho một cái gì đó trong Danh sách :: * Util * hoặc Array :: Utils, nhưng không có gì. Bạn có thể đặc sắc hơn không? – hexcoder

3

Điều đó sẽ làm:

$a=[]; 
$#$a=4; 
+0

Tôi đồng ý, tương tự '$ a = []; $ a -> [2] = 0; 'cũng nên làm. Nhưng liệu có thể trong một tuyên bố? Có lẽ không phải không có sự hỗ trợ từ một mô-đun. – hexcoder

1

Bối cảnh: Trong tôi kịch bản thử nghiệm Tôi muốn có thể so sánh nội dung mảng một cách chính xác. Ví dụ tôi muốn phân biệt giữa 'không được chỉ định' và 'được gán với giá trị không xác định'.

Bạn có thể kiểm tra xem liệu chỉ mục có kết thúc hay không. Ngoài ra, không có nhiều bạn có thể làm.

$x = []; 
undef $x->[9999]; 
print scalar @$x; 

in 10000. Các undef $x->[9999] tương đương với $x->[9999] = undef; Bởi vì không ai trong số các yếu tố 0-9998 tồn tại, perl sẽ kỳ diệu gán tất cả các yếu tố can thiệp để undef.

+0

Cảm ơn. Tôi không đồng ý với 'perl sẽ chỉ định một cách kỳ diệu tất cả các yếu tố can thiệp để undef'. Như bạn có thể thấy trong các lỗ đầu ra gỡ lỗi đầu tiên của tôi cho thấy là 'khe trống'. Nếu chúng được __assigned__ 'undef', trình gỡ lỗi sẽ hiển thị 'undef' tại đây. Tôi đã thử điều đó, nhưng không cho thấy điều này trong câu hỏi. – hexcoder

+0

@hexcoder: Đó là bởi vì mặc dù giá trị của chúng không được xác định, chúng không có giá trị undef. Sắc thái kỳ lạ. – DavidO

+0

@DavidO: Đúng. trong trình gỡ rối có sự khác biệt giữa 'x @ x' và' x \ @ x'. Đầu tiên sẽ hiển thị 'undef', 'khe trống' thứ hai. Và 'p @ x' sẽ đưa ra cảnh báo về các giá trị chưa được khởi tạo. – hexcoder

Các vấn đề liên quan