如何在多维数组中复制和/或重新分配数组元素?

时间:2018-10-23 13:19:54

标签: perl multidimensional-array replicate

代码在循环中的某处变得混乱!请帮我解决。

详细信息

使用参考元素复制和/或重新分配多维数组中的大多数数组元素。

  • 文件-1:数组索引和需要在原始数组中维护的元素的列表。

  • 文件2:原始多维数组,需要使用上述信息进行重写。除了上述元素,其余所有元素都必须重新分配。

  • 文件3:预期输出(重新分配的数组元素)

注意:除了file1的数组索引外,所有索引的其余部分都将替换为参考行。参考线通常出现在数组的第一行中。
在修改后的数组中,不需要参考线。

文件1:

ID1    2    E1,E4
ID2    5    E6,E7,E9
ID3    1    E3

文件2:

ID1.txt

Ref K L M N O P A B C D
E1 S H G U S K R E K K
E2 S L G N O P A B C D
E3 S L G N O P A B C D
E4 U L G G O P A B C D
E5 U L M G O P A J C D
E6 U L M G O P A J C D
E7 U L M G O P A J C D
E8 U L M G O P A J C D
E9 S L M N O P A J C D
E10 S L M N O P A J C D
.
.
.

文件3:预期输出

new_ID1.txt

E1    K L G N O P A B C D
E2    K L M N O P A B C D
E3    K L M N O P A B C D
E4    K L G N O P A B C D
E5    K L M N O P A B C D
E6    K L M N O P A B C D
E7    K L M N O P A B C D
E8    K L M N O P A B C D
E9    K L M N O P A B C D
E10    K L M N O P A B C D
.
.
.

在预期的输出(new_ID1.txt)中,从原始数组维护“ E1”和“ E4”的数组的第二个索引。其他所有内容都由“ E2,E3,E5 ...”中的参考行替换。

代码

#!/usr/bin/perl 

use strict;
use warnings;

my %HoHoA = ();

open(IN,"ids.txt");
my @ids = <IN>; chomp @ids; close IN;

open(IN2,"indices_and_values.txt");

while(my $l = <IN2>)
{
    chomp $l;
my @tmp = split "\t", $l;
my $lid = $tmp[0];
my $pos = $tmp[1];
my @gps = @tmp[2..$#tmp];

    foreach my $g (@gps)
    {
        push @{$HoHoA{$lid}{$g}}, $pos;
    }
}
close IN2;


foreach my $outer (sort keys %HoHoA)
{
open(IN3,"$outer.txt");
my @rS = <IN3>; chomp @rS; close IN3;

    my @orgArr = (); my @refArr = (); my @newArr = ();
    foreach my $unk (@rS) 
    { 
        @orgArr = split "\t", $unk;
        if($unk =~ /^Ref/)
        { 
            @refArr = split "\t", $unk;
            next;
        }
    foreach my $inner (sort keys %{$HoHoA{$outer}})
    {
        if($inner =~ /^$orgArr[0]/)
        {
            foreach my $ele (sort {$a <=> $b} @{$HoHoA{$outer}{$inner}})
            {
                $refArr[$ele] = $orgArr[$ele];
            }
        }
        #else
        #{
        #}
    }
    print ">$orgArr[0]\t";
    print join("\t",@refArr[1..$#refArr]);
    print "\n";
}
    @rS = ();
    print "\n";

}

2 个答案:

答案 0 :(得分:2)

显示的代码很完美,但是有点太复杂了;您可能对嵌套数据结构的操作迷失了方向。这是另一种更简单的方法。

将“参考”文件([2, 4])中的信息解析为哈希File-1。我将数据索引放置在arrayref中,以允许一行有多个索引。然后一行一行地进行操作,用这些索引替换具有键的行中的数据,并随即打印输出。

(E1 => [2, ...], ..)

新文件(为便于阅读,显示了两个空格而不是实际的选项卡)

E1  K  L  G  N  O  P  A  B  C  D
E2  K  L  M  N  O  P  A  B  C  D
E3  K  L  M  N  O  P  A  B  C  D
E4  K  L  G  N  O  P  A  B  C  D
E5  K  L  M  N  O  P  A  B  C  D
E6  K  L  M  N  O  P  A  B  C  D
E7  K  L  M  N  O  P  A  B  C  D
E8  K  L  M  N  O  P  A  B  C  D
E9  K  L  M  N  O  P  A  B  C  D
E10  K  L  M  N  O  P  A  B  C  D

请注意,给定的输入文件恰好具有与参考线相同的条目,以便在许多感兴趣的索引处进行替换-因此我们在上面的输出中看不到那些“更改”。 (我通过更改输入文件进行了测试,以便能够看到。)

答案 1 :(得分:1)

如果我正确理解了您的问题说明,这是一种方法:

#!/usr/bin/perl

use strict;
use warnings;

my %keep_idx;

open FILE, "file-1" or die "Couldn't open file-1";
while(<FILE>) {
    my (undef, $idx, $id_str) = split /\s+/;
    my @ids = split /,/, $id_str;
    foreach my $id (@ids) {
        $keep_idx{$id}{$idx} = 1;
    }
}
close FILE;

open FILE, "file-2" or die "Couldn't open file-2";
open OUTFILE, ">file-3" or die "Couldn't open file-3";
my (undef, @ref) = split /\s+/, <FILE>;
while(<FILE>) {
    my ($id, @src) = split /\s+/;
    my $line = "$id";
    for (my $i = 0; $i <= $#src; $i++) {
        my $e = $keep_idx{$id}{$i} ? $src[$i] : $ref[$i];
        $line .= " $e";
    }
    print OUTFILE "$line\n";
}
close OUTFILE;
close FILE;