从技术上讲,Perl中没有多维数组,但您可以在Perl中使用单维数组,就好像它们有多个维度一样。
在Perl中,数组的每个元素都可以是对另一个数组的引用,但从语法上讲,它们看起来像是一个二维数组。
我想在Perl中将二维整数数组转换为字符串。我已经声明了如下的二维整数数组:
my @array1=[[1,2,3],[1,2,3],[1,2,3]];
OR
my @array2=((1,2,3),(1,2,3),(1,2,3));
现在我需要创建一个将字符串作为"{{1,2,3},{1,2,3},{1,2,3}}"
返回的子例程。我尝试了以下子程序:
sub TwoDArrayOutputString {
my ($outputs)= @_;
my $finaloutput="{";
foreach my $output ($outputs) {
foreach my $out (@$output) {
$finaloutput.="{"."}";
#$finaloutput.="{".join(',',@output)."}";
}
$finaloutput.=",";
}
$finaloutput.="}";
return $finaloutput;
}
sub TwoDArrayOutputString1 {
my ($outputs)= @_;
if ( ref($outputs) eq "REF" ) {$outputs = ${$outputs};}
my $finaloutput="{";
foreach my $output ($outputs) {
foreach my $out (@$output) {
$finaloutput.="{"."}";
#$finaloutput.="{".join(',',@output)."}";
}
$finaloutput.=",";
}
$finaloutput.="}";
return $finaloutput;
}
sub TwoDArrayOutputString2{
my ($array)= @_;
my $finaloutput="{";
for my $row ( 0..$#array ) {
my @columns = @{ $array[$row] }; # Dereferencing my array reference
$finaloutput.="{";
for my $column ( @columns ) {
$finaloutput.=$column.",";
}
$finaloutput=substr($finaloutput,0,length($finaloutput)-1);
$finaloutput.="}".",";
}
$finaloutput=substr($finaloutput,0,length($finaloutput)-1);
$finaloutput.="}";
return $finaloutput;
}
print TwoDArrayOutputString(@array1)."\n";
print TwoDArrayOutputString1(@array1)."\n";
print TwoDArrayOutputString2(@array1)."\n"."\n"."\n"."\n";
print TwoDArrayOutputString(@array2)."\n";
print TwoDArrayOutputString1(@array2)."\n";
print TwoDArrayOutputString2(@array2)."\n"."\n"."\n"."\n";
输出:
{{}{}{},}
{{}{}{},}
}
{,}
{,}
}
我的预期输出为{{1,2,3},{1,2,3},{1,2,3}}
。
答案 0 :(得分:2)
首先,你的两种语法都是错误的(与你认为他们认为的相比):
my @array1=[[1,2,3],[1,2,3],[1,2,3]];
这导致@array1
持有对匿名数组的单个引用,当我认为你想要的时候,它进一步保存对三个匿名数组的三个引用:
my $array1 = [[1,2,3],[1,2,3],[1,2,3]];
$array1
现在是对一个数组的引用,该数组包含对三个匿名数组的三个引用。
my @array2=((1,2,3),(1,2,3),(1,2,3));
在这种情况下,你只是在欺骗自己所有额外的括号:你所拥有的只是一个元素为1, 2, 3, 1, 2, 3, 1, 2, 3
的数组。
你说
现在我需要创建一个子程序,它将字符串返回为{{1,2,3},{1,2,3},{1,2,3}}。
这是一个奇怪的要求。为什么你需要创建这样一个子程序?
如果您想将数组序列化为字符串,最好使用其中一种更标准且可互操作的方式,并选择JSON,YAML等格式,XML,Data::Dumper或其他。
例如:
$ perl -MJSON::MaybeXS=encode_json -E '@array1=([1,2,3],[1,2,3],[1,2,3]); say encode_json \@array1' [[1,2,3],[1,2,3],[1,2,3]]
或
$ perl -MData::Dumper -E '@array1=([1,2,3],[1,2,3],[1,2,3]); say Dumper \@array1' $VAR1 = [ [ 1, 2, 3 ], [ 1, 2, 3 ], [ 1, 2, 3 ] ];
或
$ perl -MYAML::XS -E '@array1=([1,2,3],[1,2,3],[1,2,3]); say Dump \@array1' --- - - 1 - 2 - 3 - - 1 - 2 - 3 - - 1 - 2 - 3
或
$ perl -MXML::Simple -E '@array1=([1,2,3],[1,2,3],[1,2,3]); say XMLout(\@array1)'
<opt>
<anon>
<anon>1</anon>
<anon>2</anon>
<anon>3</anon>
</anon>
<anon>
<anon>1</anon>
<anon>2</anon>
<anon>3</anon>
</anon>
<anon>
<anon>1</anon>
<anon>2</anon>
<anon>3</anon>
</anon>
</opt>
如果您的目的是学习如何遍历多维结构并进行打印,那么正确地进行操作需要注意一些细节。您可以研究YAML::Tiny的来源:
sub _dump_array {
my ($self, $array, $indent, $seen) = @_;
if ( $seen->{refaddr($array)}++ ) {
die \"YAML::Tiny does not support circular references";
}
my @lines = ();
foreach my $el ( @$array ) {
my $line = (' ' x $indent) . '-';
my $type = ref $el;
if ( ! $type ) {
$line .= ' ' . $self->_dump_scalar( $el );
push @lines, $line;
} elsif ( $type eq 'ARRAY' ) {
if ( @$el ) {
push @lines, $line;
push @lines, $self->_dump_array( $el, $indent + 1, $seen );
} else {
$line .= ' []';
push @lines, $line;
}
} elsif ( $type eq 'HASH' ) {
if ( keys %$el ) {
push @lines, $line;
push @lines, $self->_dump_hash( $el, $indent + 1, $seen );
} else {
$line .= ' {}';
push @lines, $line;
}
} else {
die \"YAML::Tiny does not support $type references";
}
}
@lines;
}
现在,对于你的简单案例,你可以这样做:
#!/usr/bin/env perl
use feature 'say';
use strict;
use warnings;
my @array = ([1, 2, 3], [4, 5, 6], [7, 8, 9]);
say arrayref_to_string([ map arrayref_to_string($_), @array]);
sub arrayref_to_string { sprintf '{%s}', join(q{,}, @{$_[0]}) }
输出:
{{1,2,3},{4,5,6},{7,8,9}}
答案 1 :(得分:1)
您可以执行以下操作:
my @array2=((1,2,3),(1,2,3),(1,2,3));
PS:我不理解你的例子中的第二个数组,即my @array2=(1,2,3,1,2,3,1,2,3);
。它基本上只是 private SurfaceView preview=null;
private SurfaceHolder previewHolder=null;
private Camera camera=null;
private boolean inPreview=false;
private boolean cameraConfigured=false
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
preview=(SurfaceView)findViewById(R.id.preview);
previewHolder = preview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
private void startPreview() {
if (cameraConfigured && camera!=null) {
camera.setDisplayOrientation(90);
camera.startPreview();
inPreview=true;
}
}
private Camera.Size getBestPreviewSize(int width, int height,
Camera.Parameters parameters) {
Camera.Size result=null;
for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
if (size.width<=width && size.height<=height) {
if (result == null) {
result = size;
} else {
int resultArea = result.width * result.height;
int newArea = size.width * size.height;
if (newArea > resultArea) {
result = size;
}
}
}
}
camera.setDisplayOrientation(90);
return(result);
}
private void initPreview(int width, int height) {
if (camera!=null && previewHolder.getSurface()!=null) {
try {
camera.setPreviewDisplay(previewHolder);
}
catch (Throwable t) {
Log.e("Preview-surfaceCallback",
"Exception in setPreviewDisplay()", t);
Toast
.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_LONG)
.show();
}
if (!cameraConfigured) {
Camera.Parameters parameters=camera.getParameters();
Camera.Size size=getBestPreviewSize(width, height,
parameters);
if (size!=null) {
parameters.setPreviewSize(size.width, size.height);
camera.setParameters(parameters);
cameraConfigured=true;
}
}
}
}
SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback() {
public void surfaceCreated(SurfaceHolder holder) {
// no-op -- wait until surfaceChanged()
}
public void surfaceChanged(SurfaceHolder holder,
int format, int width,
int height) {
initPreview(width, height);
startPreview();
}
public void surfaceDestroyed(SurfaceHolder holder) {
// no-op
}
};
protected void onPause() {
if (inPreview) {
camera.stopPreview();
}
camera.release();
camera=null;
inPreview=false;
super.onPause();
}
protected void onResume() {
super.onResume();
camera = Camera.open();
startPreview();
}
。
答案 2 :(得分:1)
一种方式可能是Data::Dumper
。但是正确地将array
或array-refs
传递给Dumper
。您的@array2
是一维数组。
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my @array1=[[1,2,3],[1,2,3],[1,2,3]];
my $string = Dumper(@array1);
$string =~ s/\n|\s+|.*?=|;//g;
$string =~ s/\[/\{/g;
$string =~ s/\]/\}/g;
print $string."\n";
<强>输出:强>
{{1,2,3},{1,2,3},{1,2,3}}