【问题标题】:perl - push unique elements into array and create variables from the unique elementsperl - 将唯一元素推入数组并从唯一元素创建变量
【发布时间】:2019-04-11 23:18:22
【问题描述】:

我正在使用 Perl。

我从一个包含两列的制表符分隔的 txt 文件开始。

cat1    val1
cat1    val2
cat2    val3 
cat3    val4
cat1    val5
cat4    val6

我想将第 1 列中的唯一类别推送到一个数组中并创建与这些唯一类别同名的空变量

所以最后我会:

@unique_categories = ("cat1", "cat2", "cat3", "cat4");

$cat1 = '';
$cat2 = '';
$cat3 = '';
$cat4 = '';

这是我尝试过的:

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

open(my $file,'<',"file.txt") || die ("Could not open file $!"); #input file

my $categories = '';
my @categories_unique = '';

while(<$file>){
    chomp;
    my $line = $_;
    my @elements = split ("\t", $line);
    $categories = $elements[0]; #everything seems fine until here
    push(@categories_unique, $categories) unless grep{$_ eq $categories} @categories_unique; #with this line I want to store the unique values in an array
    #here I want to create the empty variables, but don't know how to
}

【问题讨论】:

  • 为什么要创建那些空变量?使用这些类别作为哈希的键听起来更合理;有什么理由不这样做?

标签: perl


【解决方案1】:

使用动态创建名称的变量很危险,请参阅 Why it's stupid to `use a variable as a variable name'A More Direct Explanation of the Problem

在 Perl 中,您可以使用散列来保留唯一值,也可以代替未知名称的变量。它也比每次迭代整个数组要快得多。

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

open my $fh, '<', 'file.txt' or "Could not open file $!";
my %categories;

while (my $line = <$fh>) {
    chomp $line;
    my @elements = split /\t/, $line;
    ++$categories{ $elements[0] };
}
my @categories = keys %categories;

现在,%categories 哈希值只是该类别出现的次数。例如,$categories{cat1} 是 3。如果您决定要使用每个类别的值,则只需替换

++$categories{ $elements[0] };

push @{ $categories{ $elements[0] } }, $elements[1];

【讨论】:

    【解决方案2】:

    第一次尝试还不错。这就是你需要的

    #! /usr/bin/perl
    use strict;
    use warnings;
    
    open(my $file,'<',"file.txt") || die ("Could not open file $!"); #input file
    
    my %categories_unique = ();
    my @categories_unique = ();
    
    while(<$file>){
        chomp;
        my $line = $_;
        my @elements = split ("\t", $line);
        $categories = $elements[0]; #everything seems fine until here
        $categories_unique{$categories} = 1; # Use the fact that keys in a hash are unique
    }
    
    @categories_unique = keys %categories_unique;
    {
        no strict 'refs'; # allows access to symbol table
        *{$_} = undef() foreach @categories_unique; create a symbol table entry 
    }
    

    【讨论】:

    • 除了背书动态创建变量的主要问题外,还有一些小问题:
    • 1) 将空列表分配给空数组和空哈希是没有用的。 2) 从$_ 开始,稍后切换到$line 没有任何意义。坚持一个或另一个。 3) 除非是' ',否则 split 的第一个参数是正则表达式模式,所以不要假装它不是。 4)不要在需要之前声明变量。声明变量的目的是限制它们的范围。 5) 这是我第一次看到用undef() 代替undef。这很奇怪。 6) _unique 并没有真正向这些 var 名称添加任何内容。
    猜你喜欢
    • 2020-04-14
    • 2014-09-14
    • 2012-04-28
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    相关资源
    最近更新 更多