perl - помещает уникальные элементы в массив и создает переменные из уникальных элементов - PullRequest
0 голосов
/ 11 апреля 2019

Я работаю в Perl.

Я начинаю с текстового файла с разделителями табуляции с двумя столбцами.

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
}

Ответы [ 2 ]

4 голосов
/ 11 апреля 2019

Наличие переменных с динамически создаваемыми именами опасно, см. Почему глупо `использовать переменную в качестве имени переменной ' и Более прямое объяснение проблемы .

В 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];
0 голосов
/ 11 апреля 2019

Неплохая первая попытка. вот что тебе нужно

#! /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 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...