Создание уникального массива perl

В настоящее время у меня очень простая проблема с получением результата от команды оболочки с обратным тактом. Я извиняюсь, что проблема довольно проста.

У меня есть отсортированный массив (@valid_runs), который, как я знаю, содержит последовательные, повторяющиеся элементы. Я хочу использовать backticks для вывода этого массива в uniq. Я хочу захватить STDOUT в массиве. Я пытаюсь сделать это так.

@unique_valids = `echo '@valid_runs' | uniq`;
print @unique_valids;

Это утверждение для печати ничего не дает. В этом отношении ни один не делает этого.

@unique_valids = `echo '@valid_runs'`;
print @unique_valids;

Я знаю, как использовать uniq и echo. Это кажется довольно странным для меня. Я думаю, что это больше связано с массивами Perl, чем с правильным использованием этих команд. Я искал немного в другом месте, поэтому, пожалуйста, не обижайте меня отрицательными голосами только потому, что решение может показаться тривиальным. Еще раз спасибо за ваше время.

ПРИМЕЧАНИЕ о решениях. Решение TLP является наиболее простым в плане решения уникальной проблемы. Я достаточно гибок, поскольку во всех ответах предлагалось не делать системный вызов для этой проблемы. Если Uniq-функция Perl совпадает с Uniq-Unix, тогда массив должен оставаться отсортированным.

Решение Джона Корбетта работает хорошо, если вас не интересует отсортированный результат.

4 ответа

Решение

Использование системных вызовов для чего-то, что может быть легко выполнено с помощью Perl-кода, не очень хорошая идея. Модуль List:: MoreUtils имеет функцию uniq, которая делает то, что вам нужно:

use List::MoreUtils qw(uniq);

my @unique = uniq @runs;

Подпрограмма внутри самого модуля очень проста, точно так же, как и ответ глаубера:

sub uniq (@) {
    my %seen = ();
    grep { not $seen{$_}++ } @_;
}

Вы должны просто сохранить массив в хэш, потому что ключи хеша всегда уникальны. Вы можете сделать это так:

my %temp_hash = map { $_ => 1 } @valid_runs;
my @unique_valids = keys %temp_hash;

в любом случае это лучший способ сделать это. Здесь нет необходимости использовать обратные тики (я стараюсь избегать их как можно больше).

Это легко сделать в Perl. Вот довольно неясный, но интересный способ дедупликации массива:

@dedup = grep !$seen{$_}++ @orig_array;

Выясните, что это делает, проверив документацию для функции perl grep,

Если вы должны использовать uniqВам, вероятно, нужно поместить каждый элемент массива в отдельную строку.

join("\n", @your_array)

должен достичь этого.

#!/usr/bin/perl
use warnings;

@a = (1, 2, 3, 3, 4, 4, 5);

$cmd = "/usr/bin/uniq <<EOF\n";
$cmd .= $_."\n" foreach (@a);
$cmd .= "EOF\n";

$result = `$cmd`;
print "Cmd: $cmd\n";
print "Result is $result";

@u = split /\n/,$result;
print "After ",join " ",@u,"\n";

Это делает то, что вы спрашиваете, но ответ theglauber все еще лучше Perl.

Другие вопросы по тегам