开发者

How do I find which elements in one array aren't in another?

I am new to programming and hence I am stuck on a basic level problem.

Following is code I wrote for comparison. But the result I get does not make sense to me. I would appreciate if someone could tell me what is going wrong.

There are two arrays: @array1 , @array2 of unequal length.

I wish to compare both and list down values not present in @array1.

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


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

Adapting the code you posted:

#!/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";
}


If you're doing this for a test, which I assume you are I would highly suggest is_deeply in the newer versions of Test::More

You'll have to update Test::More

cpanp install Test::More

or if you're on perl 5.5

cpan Test::More

Then you'll have use it

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

If you're not doing this for testing, but you're doing this for introspective purposes and the arrays are small, I'd suggest using XXX:

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

Then you'll have use it

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


That's some pretty clever code you've got there. Your code is more or less identical to what the Perl FAQ says. I might be tempted to do this, however:

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

This gets everything in @array1 that's not in @array2, but avoiding all of those out-of-style looping constructs (yay for functional programming). Though what I'd really do is this:

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

Then you can just do:

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

Or you can go to CPAN. List::Compare::Functional::complement() does what you want, though the syntax is reversed.


Swap @array1 and @array2 in your code?


For simple values like strings or numbers, the following should work

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);

Should give :

$VAR1 = 'host2';
$VAR2 = 'host3';
$VAR3 = 'host4';
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜