В Perl, там созданный способом сравнить два массива для равенства?

Легко выписать большой список команд/ярлыков, но трудно помнить их всех без практики.

Внимание на одну новую команду за один раз. Когда это становится автоматическим, скажите после использования его в течение недели или два, добавьте другого к своему репертуару.

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

, По моему опыту, было легче, когда я пытался не взять слишком много сразу.

51
задан G. Cito 19 December 2014 в 18:48
поделиться

6 ответов

Появился новый оператор интеллектуального сопоставления :

#!/usr/bin/perl

use 5.010;
use strict;
use warnings;

my @x = (1, 2, 3);
my @y = qw(1 2 3);

say "[@x] and [@y] match" if @x ~~ @y;

Относительно Array :: Compare :

Внутренне компаратор сравнивает два массива по использование соединения для превращения обоих массивов в строки и сравнение строк с помощью eq .

Думаю, это допустимый метод, но пока мы используем сравнения строк, я бы предпочел использовать что-то вроде:

#!/usr/bin/perl

use strict;
use warnings;

use List::AllUtils qw( each_arrayref );

my @x = qw(1 2 3);
my @y = (1, 2, 3);

print "[@x] and [@y] match\n" if elementwise_eq( \(@x, @y) );

sub elementwise_eq {
    my ($xref, $yref) = @_;
    return unless  @$xref == @$yref;

    my $it = each_arrayref($xref, $yref);
    while ( my ($x, $y) = $it->() ) {
        return unless $x eq $y;
    }
    return 1;
}

Если массивы, которые вы сравниваете, большие, их объединение потребует много работы и много памяти, чем простое сравнение каждого элемента по одному.

Обновление: Конечно, следует проверить такие заявления. Простые тесты:

#!/usr/bin/perl

use strict;
use warnings;

use Array::Compare;
use Benchmark qw( cmpthese );
use List::AllUtils qw( each_arrayref );

my @x = 1 .. 1_000;
my @y = map { "$_" } 1 .. 1_000;

my $comp = Array::Compare->new;

cmpthese -5, {
    iterator => sub { my $r = elementwise_eq(\(@x, @y)) },
    array_comp => sub { my $r = $comp->compare(\(@x, @y)) },
};

Это наихудший сценарий, когда elementwise_eq должен пройти через каждый элемент в обоих массивах 1_000 раз, и он показывает:

             Rate   iterator array_comp
iterator    246/s         --       -75%
array_comp 1002/s       308%         --

С другой стороны,

56
ответ дан 7 November 2019 в 09:57
поделиться

Если вы используете Perl 5.10 или новее, вы можете использовать оператор интеллектуального сопоставления .

if (@array1 ~~ @array2) {...}
8
ответ дан 7 November 2019 в 09:57
поделиться

Не встроено, но есть Array :: Compare .

Это одна из операций, которая, по моему мнению, не входит в ядро ​​Perl. дидактические причины - то есть, если вы пытаетесь это сделать, вероятно, что-то не так. Я думаю, что наиболее показательным примером этого является отсутствие основной функции read_entire_file ; По сути, предоставление этой функции в ядре заставит людей подумать, что это хорошая идея , но вместо этого Perl разработан таким образом, что он мягко подталкивает вас к обработке файлов построчно. , который, как правило, намного более эффективен и в остальном - лучшая идея, но начинающим программистам это редко бывает комфортно, и им нужно некоторое поощрение, чтобы достичь этого.

То же самое применимо и здесь: вероятно, есть гораздо лучший способ сделать определение, которое вы пытаетесь достичь, сравнив два массива. Не обязательно , но возможно. Итак, Perl подталкивает вас к размышлению о других способах достижения вашей цели.

14
ответ дан 7 November 2019 в 09:57
поделиться

Perl 5.10 предоставляет вам оператор интеллектуального сопоставления.

use 5.010;

if( @array1 ~~ @array2 )
{
    say "The arrays are the same";
}

В противном случае, как вы сказали, у вас будет собственный верхний рейтинг.

9
ответ дан 7 November 2019 в 09:57
поделиться

В Test :: More есть функция is_deeply (), которая также будет отображать, где именно различаются структуры, или Test :: Deep ' s eq_deeply (), который не требует тестовой оснастки (и просто возвращает истину или ложь).

22
ответ дан 7 November 2019 в 09:57
поделиться

Если регистр - единственное отличие, вы можете просто использовать:

if (lc "@array1" eq lc "@array2") {...}

В то время как «@ array1» возвращает то же самое, что и join ("", @ array1 )

1
ответ дан 7 November 2019 в 09:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: