Comparing two arrays, removing items that match

arrays, perl

Solution

There's no reason to explicitly loop here. You want to filter names: that's a `grep`. You want to check membership: that could be done by a `grep` too.

@names = grep {my $name = $$_[0]; not grep $_ eq $name, @employees} @names;

The repeated scanning of the inner array isn't particularly efficient; it can be avoid by pre-populating a set (really a hash) ahead of time.

my %employees = map +($_ => 1), @employees;
@names = grep !$employees{$$_[0]}, @names;

Problem

I have two arrays, `@names` and `@employees`, that are filled with strings that represent names. `@names` is 2 dimentional, holding references to anonymous arrays, but the location of the data we care about is at `@names[i][0]`. I want to loop through `@names` and find which names are not in `@employees`. At first I thought that looping through `@names` backwards, comparing it to `@employees` and deleting any matches from `@names` would work, but I run into some errors. Here's what I have: ``` for my $i (reverse(0 .. $#names)) { foreach my $employee (@employees) { if ($names[$i][0] eq $employee) { # line 67 splice(@names, $i, 1); } } } ``` I run into this error: Use of uninitialized value in string eq at script.pl line 67, line 2. The strings are all defined in the array. So I'm guessing that this is caused from me deleting elements in the array while I am looping through it, but I thought that looping through the array backwards would prevent an issue like this from happening. So where am I going wrong in my loop? Also, I've been really struggling with this loop and that hints to me that something is wrong with my entire thought process. Is there a better method to do this?

Original source

Related problems