Thomas Anowez
Thomas Anowez

Reputation: 91

Perl - Remove element from an array if already exist in another

I've a question about perl embeded functions. In your opinion, "map" function could help me for made a pop of all elements in an array, if already exist it in another array?

These are the arrays:

Array named OLDER_EVENTS:

my @older_events = (
    surname => [
        qw(
            red
            brown
            simpson
            donald         
        )
    ],
    date => [
        qw(
            2018/02/14
            2018/03/09
            2018/05/01
            2018/08/02
        )
    ],
    time => [
        qw(
            01:00:52
            01:06:41
            03:24:31
            19:14:31            
        )
    ]
);

ARRAY NAMED NEW ELEMENTS:

my @new_events = (
    surname => [
        qw(
            simpson
            donald         
            blanco
            ernald
        )
    ],
    date => [
        qw(
            2018/03/09
            2018/08/02
            2018/08/01
            2018/08/14
        )
    ],
    time => [
        qw(
            03:24:31
            19:14:31            
            00:03:16
            09:21:45
        )
    ]
);

In new events, last two entries are new, so, I would pop elements 1 and 2 from @new_events because it already exist in @older_events

How could I do it, with a smart solution?

Have I to use a third array, or, could I pop it from @older_events?

Thanks for your attention

Upvotes: 1

Views: 202

Answers (1)

ikegami
ikegami

Reputation: 385556

First of all, you're using arrays for key-value pairs. This is not useful.

my %older_events = @older_events;
my %newer_events = @newer_events;

Secondly, your want to perform operations on records, but your data isn't organized into records.

my @older_events =
   map {
      +{
         surname => $older_events->{ surname }[$_],
         date    => $older_events->{ date    }[$_],
         time    => $older_events->{ time    }[$_],
      }
   }
      0..$#{ $older_events->{surname} };

my @newer_events =
   map {
      +{
         surname => $newer_events->{ surname }[$_],
         date    => $newer_events->{ date    }[$_],
         time    => $newer_events->{ time    }[$_],
      }
   }
      0..$#{ $newer_events->{surname} };

Thirdly, we need a quick way to lookup if an event is in @older_events.

sub key { join "\0", @{ $_[0] }{qw( surname date time )} }

my %older_event_by_key =
   map { key($_) => $_ }
      @older_events;

Finally, we can grep

@newer_events =
   grep { !$old_event_by_key{ key($_) } }
      @newer_events;

Upvotes: 7

Related Questions