2009-11-18 3 views
1

Je suis novice en programmation et je suis donc bloqué sur un problème de base.Comment puis-je trouver quels éléments d'un tableau ne sont pas dans un autre?

Voici le code que j'ai écrit pour la comparaison. Mais le résultat que je reçois n'a pas de sens pour moi. J'apprécierais que quelqu'un puisse me dire ce qui ne va pas.

Il existe deux tableaux: @array1, @array2 de longueur inégale.

Je souhaite comparer les valeurs de liste et de liste non présentes dans @ array1.

my %temp = map {$_,$_}@array2; 
for (@array1){ 
next if exists $temp{$_}; 
open (FILE, ">>/filename") or die "$!"; 
print FILE "$_\n"; 
close(FILE); 
} 
+2

Voir aussi votre entrée, votre sortie, et votre résultat attendu. – dave4420

+2

Le pourquoi est généralement un élément essentiel pour de telles questions novices, sinon ceux d'entre nous aidant ne peuvent pas identifier les "problèmes X-Y". –

Répondre

10

Voir la FAQ How do I compute the difference of two arrays? How do I compute the intersection of two arrays?

Adapter le code affiché:

#!/usr/bin/perl 

use strict; use warnings; 

my @x = 1 .. 10; 
my @y = grep { $_ % 2 } @x; 

my %lookup = map { $_ => undef } @y; 

for my $x (@x) { 
    next if exists $lookup{$x}; 
    print "$x\n"; 
} 
+3

Je fais habituellement 'my% seen; @seen {@y} = (1) x @y; 'au lieu de' map', mais ils équivalent à la même chose. – Ether

+0

@Ether - Parce que la microoptimisation est amusante, mes becnhmarks montrent qu'elle est légèrement plus rapide que 'map'. Intelligent et efficace. –

+0

Je ne peux pas résister à l'aide de tranches de hash! :) – Ether

1

Swap @array1 et @array2 dans votre code?

5

Si vous faites cela pour un test, que je suppose que vous êtes, je vous suggère fortement is_deeply dans les nouvelles versions de test :: Plus

Vous devez mettre à jour Test :: Plus

cpanp install Test::More 

ou si vous êtes en perl 5,5

cpan Test::More 

Ensuite, vous aurez l'utilisent

use Test::More; 
tests => 1 
is_deeply (\@arr1, \@arr2, 'test failed'); 

Si vous ne faites pas cela pour le test, mais vous faites cela à des fins introspectifs et les tableaux sont petits, je suggère d'utiliser XXX:

cpanp install http://search.cpan.org/CPAN/authors/id/I/IN/INGY/XXX-0.12.tar.gz 

Ensuite, vous aurez l'utilisent

use XXX; 
YYY [ \@arr1, \@arr2 ]; 
4

C'est un code assez intelligent que vous avez ici. Votre code est plus ou moins identique à ce que dit la FAQ Perl. Je pourrais être tenté de le faire, cependant:

my %tmp = map { $_ => 1 } @array2; 
my @diff = grep { not exists $tmp{$_} } @array1; 

Cela devient tout @array1 qui est pas @array2, mais en évitant toutes ces constructions de mise en boucle hors de style (yay pour la programmation fonctionnelle). Bien que ce que j'avais vraiment faire est la suivante:

sub comp (\@\@) { 
    my %t = map { $_ => 1 } @{$_[1]}; 
    return grep { not exists $t{$_} } @{$_[0]}; 
} 

Ensuite, vous pouvez juste faire:

my @diff = comp(@array1, @array2); # get items in @array1 not in @array2 
@diff = comp(@arraty2, @array1); # vice versa 

Ou vous pouvez aller à CPAN. List::Compare::Functional::complement() fait ce que vous voulez, bien que la syntaxe soit inversée.

0

Pour des valeurs simples comme des chaînes ou des chiffres, les éléments suivants devraient travailler

my @result; 
my $hosts = [qw(host1 host2 host3 host4 host5)]; 
my $stie_obj = [qw(host1 host5 host6)]; 

@result = map { my $a=$_; my $b=grep {/$a/} @$site_obj; $b==0 ? $a :() } @$hosts; 
print Dumper (@result); 

devrait donner:

$VAR1 = 'host2'; 
$VAR2 = 'host3'; 
$VAR3 = 'host4'; 
Questions connexes