2014-11-18 2 views
6

Есть ли простой способ сравнения двух строковых массивов в Perl?Сравнение двух массивов простым способом с использованием Perl

@array1 = (value1, value2, value3...); 
@array2 = (value1, value3, value4...); 

мне нужно сравнение, как показано ниже на «N» Количество значений,

value1 eq value1 
value2 eq value3 
value3 eq value4 

Пожалуйста, предложите мне есть ли модуль, чтобы сделать это?

Благодаря

ответ

7

Хм ... А Моду Вы можете сказать, сравниваете ли вы массивы. Как насчет Array::Compare?

use Array::Compare; 

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

my @array1 = (value1, value2, value3...); 
my @array2 = (value1, value3, value4...); 

if ($compare->compare(\@array1, \@array2) { 
    say "Arrays are the same"; 
} else { 
    say "Arrays are different"; 
} 

Но вы также можете воспользоваться оператором smart match.

if (@array1 ~~ @array2) { 
    say "Arrays are the same"; 
} else { 
    say "Arrays are different"; 
} 
3

Perl уже имеет некоторые части для решения каких-либо операций списка.

См. List::Util и List::MoreUtils.

my $arrays_are_equal 
    = !List::Util::pairfirst { $a ne $b }  # first case where $a != $b 
     List::MoreUtils::zip(@array1, @array2) 
    ; 

Для этого приложения см List::Util::pairfirst и List::MoreUtils::zip

+1

Хотя этот фрагмент кода может решить вопрос, [включая пояснение] (http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причин вашего предложения кода. – msrd0

1

Эта задача достаточно проста, что не обязательно нужно использовать модуль CPAN. Вместо этого я, скорее всего, напишу свою собственную подпрограмму сравнения и поместил бы ее в свой собственный служебный модуль. Вот одна реализация, которая будет сравнивать два массива, содержащие строки и/или целые числа.

#!/usr/bin/env perl 

use strict; 
use warnings; 

my @array1 = (1..10, 'string'); 
my @array2 = (1..10, 'string'); 

my $is_same = is_same(\@array1, \@array2); 

print "is_same: $is_same\n"; 

sub is_same { 
    my($array1, $array2) = @_; 

    # immediately return false if the two arrays are not the same length 
    return 0 if scalar(@$array1) != scalar(@$array2); 

    # turn off warning about comparing uninitialized (undef) string values 
    # (limited in scope to just this sub) 
    no warnings; 

    for (my $i = 0; $i <= $#$array1; $i++) { 
    if ($array1->[$i] ne $array2->[$i]) { 
     return 0; 
    } 
    } 

    return 1; 
} 
3

Вы можете сравнить размеры обоих массивов (@a1 == @a2 в скалярном контексте), а затем сравните размер @a1 массив с размером списка индексов, которые соответствуют равные строки в обоих массивах (grep $a1[$_] eq $a2[$_], 0..$#a1),

if (@a1 == @a2 and @a1 == grep $a1[$_] eq $a2[$_], 0..$#a1) { print "equal arrays\n" } 

Увеличенная производительность ориентированная версия (не проходит через все элементы, если не нужно),

use List::Util 'all'; 

if (@a1 == @a2 and all{ $a1[$_] eq $a2[$_] } 0..$#a1) { print "equal arrays\n" } 
+1

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

Смежные вопросы