在perl中减去引用

时间:2014-10-17 16:43:53

标签: perl reference

我试图减去两组太大而无法在数组中的数据。我想像下面显示的普通数组一样减去它们。

@x = (1, 2, 3);
@x2= (2, 3, 4);

my @delta = map { my $diff = $_; map { $diff - $_ } @x2 } @x;

得到:

1-2
1-3
1-4
2-2
2-3
2-4

我目前正在使用它:

my $i = 0;
my $j = 0;
my $prot_x_var;
my $lipid_x_var;

#this section count the line in a file containing data. $#data is magnitude of the array of data.
for ( my $count = 0; $count <= $#data; ++$count ) {

#this searches the data for a specific string so $protein is not important but to define the string.
    if ( $data[$count] =~ m/\s+$protein\s+/ ) {
        ++$i;    #adds up the $i foreach specific string found
        $prot_x_var = $protein_xyz_coords->[0]->[$i]->{'x'};    #this flips through all the data points.
        #print "$prot_x_var \n";
    }

    #$POPS and $POPC are just use to find a string.
    if ( ( $data[$count] =~ m/\s+$POPS\s+/ ) || ( $data[$count] =~ m/\s+$POPC\s+/ ) ) {
        ++$j;                                                   #same as $i but for a different string
        $lipid_x_var = $lipid_xyz_coords->[1]->[$j]->{'x'};     #same as above
        #print "$lipid_x_var \n";
    }
}

我现在想要从每个$lipid_x_var$lipid_xyz_coords->[1]->[$j]->{'x'}中减去每个$prot_x_var$protein_xyz_coords->[0]->[$i]->{'x'},就像上面的数组一样。我有一个先前的问题,有人试图帮助我这是类似的,但现在必须回到使用这个想法,因为数据的大小。

2 个答案:

答案 0 :(得分:0)

我不知道您的代码与您的问题有什么关系。我只是回答这个问题。

以下是一种不将结果存储在内存中的解决方案。

my @x1 = (1, 2, 3);
my @x2 = (2, 3, 4);

for my $x1 (@x1) {
   for my $x2 (@x2) {
      print("$x1-$x2 = ", $x1-$x2, "\n");
   }
}

或者如果你想要一个迭代器,

use Algorithm::Loops qw( NestedLoops );

my @x1 = (1, 2, 3);
my @x2 = (2, 3, 4);

my $iter = NestedLoops([ \@x1, \@x2 ]);

while (my ($x1, $x2) = $iter->()) {
   print("$x1-$x2 = ", $x1-$x2, "\n");
}

答案 1 :(得分:0)

所以你的数组太大而无法存储在内存中?嗯......我会尝试将两个数组放在文件中,然后逐行读取它们,执行减法并将输出打印到新文件,这样就不会将任何完整数组存储在内存中。

例如:


x1.dat
1
2
3

x2.dat
2
3
4

test.pl
#!/usr/bin/perl

use strict;
use warnings;

# create output file
open (OUTPUT, '>', 'output.dat') or die "Failed to open output file: $!";

# loop through x1 values
open (X1, '<', 'x1.dat') or die "Failed to get x1 data: $!";
while (<X1>) {

    # get x1 value
    my $x1 = $_;

    # loop through x2 values
    open (X2, '<', 'x2.dat') or die "Failed to get x2 data: $!";
    while (<X2>) {

        # get x2 value
        my $x2 = $_;

        # get difference
        my $diff = $x1 - $x2;

        # store in output file
        print OUTPUT "$diff\n";
    } close X2;
} close X1;

# close output file
close OUTPUT;

output.dat
-1
-2
-3
0
-1
-2
1
0
-1

这不会将任何巨型数组存储在内存中,而只会跟踪每个文件的简单索引。根据数组的大小判断,虽然您可能希望在循环中添加print语句,以便可以看到正在进行的进度(处理那么多数据可能需要很长时间)。希望这有帮助!


编辑:

更好的解决方案并不是每次都通过循环重新打开和关闭X2文件!使用seek从头重新读取文件。

#!/usr/bin/perl

use strict;
use warnings;

# open input files
open (X1, '<', 'x1.dat') or die "Failed to get x1 data: $!";
open (X2, '<', 'x2.dat') or die "Failed to get x2 data: $!";

# create output file
open (OUTPUT, '>', 'output.dat') or die "Failed to open output file: $!";

# loop through x1 values
while (<X1>) {

    # get x1 value
    my $x1 = $_;

    # loop through x2 values
    seek X2, 0, 0;
    while (<X2>) {

        # get x2 value
        my $x2 = $_;

        # get difference
        my $diff = $x1 - $x2;

        # store in output file
        print OUTPUT "$diff\n";
    }
}

# close input files
close X1;
close X2;

# close output file
close OUTPUT;