【问题标题】:Perl, grouping Array of Array element based on one column and conditionPerl,根据一列和条件对数组元素进行分组
【发布时间】:2015-09-11 09:04:40
【问题描述】:

我有一个四列多行的 AoA 构造。以下是数据(输入)的示例。

DQ556929    103480190   103480214   154943
DQ540839    103325247   103325275   2484
DQ566549    103322763   103322792   99
DQ699634    103322664   103322694   0
DQ544472    103322664   103322692   373
DQ709105    103322291   103322318   46
DQ705937    103322245   103322273   486
DQ699398    103321759   103321788   1211
DQ710151    103320548   103320577   692251
DQ548430    102628297   102628326   1
DQ558403    102628296   102628321   855795
DQ692476    101772501   101772529   481463
DQ544274    101291038   101291068   484047
DQ723982    100806991   100807020   1
DQ709023    100806990   100807020   3
DQ712307    100806987   100807014   0
DQ709654    100806987   100807012   571051
DQ707370    100235936   100235962   1481849

我想将所有行元素(按顺序)分组并写入文件。 条件是,如果第四列的值小于 1000 并且最小两个值彼此相邻,则将它们分组,如果值小于 1000 并且位于大于 1000 的值之间,则将它们视为单个并单独附加到同一文件中,并且值超过 1000 的也写成一个块,但不影响第 2 列和第 3 列的顺序。

这个文件是我以前的程序的输出,现在我已经尝试实现我的手,但得到了一些奇怪的结果。这是我的代码块,但不起作用。伙计们,如果我在这里很好地执行我的逻辑,我需要帮助,我对任何 cmets 作为初学者持开放态度。并在任何地方纠正我。

my @dataf= sort{ $a->[1]<=> $b->[1]} @data;
@dataf=reverse @dataf;
for(my $i>=0;$i<=$#Start;$i++)
{
    print "$sortStart[$i]\n";
    my $diff = $sortStart[$i] - $sortStart[$i+1];
    $dataf[$i][3]= $diff;
#   $IDdiff{$ID[$i]}=$diff;
}

#print Dumper(@dataf);

open (CLUST, ">> ./clustTest.txt" );
for (my $k=0;$k<=$#Start;$k++)
{   

    for (my $l=0;$l<=3;$l++)
    {
#       my $tempdataf = shift $dataf[$k][$l];
#       print $tempdataf;       

        if ($dataf[$k][3]<=1000)
        {
            $flag = 1;
            do
            {
                print CLUST"----- Cluster $clustNo -----\n";
                print CLUST"$dataf[$k][$l]\t";
                if ($dataf[$k][3]<=1000)
                {
                    $flag1 = 1;
                }else {$flag1=0;}

            $clustNo++;
            }until($flag1==0 && $data[$k][3] > 1000);

            if($flag1==0 && $data[$k][3] > 1000)
            {
                print CLUST"Singlet \n";
                print CLUST"$dataf[$k][$l]\t";
                next;
            }
        #print CLUST"$dataf[$k][$l]\t";     #@IDdiff

        }

    print CLUST"\n";
    }
}

文件中的预期输出:

单件 DQ556929 103480190 103480214 154943 DQ540839 103325247 103325275 2484

集群 1 DQ566549 103322763 103322792 99 DQ699634 103322664 103322694 0 DQ544472 103322664 103322692 373 DQ709105 103322291 103322318 46 DQ705937 103322245 103322273 486

单件 DQ699398 103321759 103321788 1211 DQ710151 103320548 103320577 692251 DQ548430 102628297 102628326 1 DQ558403 102628296 102628321 855795 DQ692476 101772501 101772529 481463 DQ544274 101291038 101291068 484047

集群 2 DQ723982 100806991 100807020 1 DQ709023 100806990 100807020 3 DQ712307 100806987 100807014 0

单件 DQ709654 100806987 100807012 571051 DQ707370 100235936 100235962 1481849

【问题讨论】:

  • 你能为给定的输入样本添加预期的输出吗?逻辑描述模糊。
  • 不要使用裸字文件句柄,不要使用 2-arg open,不要忽略 open 错误。
  • 总是use strict; use warnings;。例如,我很确定会找到my $i&gt;=0;
  • @melpomene,是的,我在 $i>=0 处收到警告,但不知道为什么会这样。它的数值等式不是吗?
  • @Kanhu my $i &gt;= 0 定义了一个包含undef 的新变量$i。然后它比较undef0(数字)。然后它将比较的结果扔掉。它在其他方面等价于my $i(另外,为什么要比较刚刚创建的变量?)。你可能打算写的是my $i = 0;

标签: arrays perl multidimensional-array


【解决方案1】:

这似乎产生了预期的输出。我不确定我是否正确理解了规范,因此可能存在错误和极端情况。

它是如何工作的:它会记住它当前输出的部分类型($section、SingletCluster)。如果它们属于一起,它将在@cluster 数组中累积行,当不兼容的行到达时,将打印集群并启动新的集群。如果要打印的集群只有一个成员,则将其视为单重态。

#!/usr/bin/perl
use warnings;
use strict;

my $section = q();
my @cluster;
my $cluster_count = 1;

sub output {
    if (@cluster > 1) {
        print "Cluster$cluster_count\n";
        $cluster_count++;

    } elsif (1 == @cluster) {
        print $section = 'Singlet', "s\n" unless 'Singlet' eq $section;
    }

    print for @cluster;
    @cluster = ();
}

my $last = 'INF';
while (<>) {
    my ($id, $from, $to, $value) = split;
    if ($value > 1000 || 1000 < abs($last - $from)) {
        output();

    } else {
        $section = 'Cluster';
    }

    push @cluster, $_;
    $last = $to;
}
output();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-15
    • 1970-01-01
    • 1970-01-01
    • 2019-02-02
    相关资源
    最近更新 更多