grepping a list of patterns in a larger list

  • Thread starter Udaykumar Kunapuli
  • Start date
U

Udaykumar Kunapuli

Hi,

I have 2 lists.

As an example:
@list1 = (1234, 345638, 3535, 93756387);
@list2 = ("375539 Linux DONE", "1234 Linux DONE", "345638 Linux EXIT", "6384643 Linux RUN", "45234 Linux RUN", "3535 Linux DONE", "93756387 Linux DONE");

I need to print out the list of elements in list2 where the first number part of the string does NOT exist in list1.

I need to get a list3 from list2 where list3 looks like below
@list3 = ("375539 Linux DONE", "6384643 Linux RUN", "45234 Linux RUN");

None of the above first number parts in list3 exist in list1, which is how I want it to be.

What would be the simplest way of doing this in Perl?

Thanks,
Uday
 
$

$Bill

Hi,

I have 2 lists.

As an example:
@list1 = (1234, 345638, 3535, 93756387);
@list2 = ("375539 Linux DONE", "1234 Linux DONE", "345638 Linux EXIT", "6384643 Linux RUN", "45234 Linux RUN", "3535 Linux DONE", "93756387 Linux DONE");

I need to print out the list of elements in list2 where the first number part of the string does NOT exist in list1.

I need to get a list3 from list2 where list3 looks like below
@list3 = ("375539 Linux DONE", "6384643 Linux RUN", "45234 Linux RUN");

None of the above first number parts in list3 exist in list1, which is how I want it to be.

What would be the simplest way of doing this in Perl?

If list1 is reasonably small, I'd just grep list2 for each item in list1:

use strict;
use warnings;

my @list1 = (1234, 345638, 3535, 93756387);
my @list2 = ("375539 Linux DONE", "1234 Linux DONE", "345638 Linux EXIT",
"6384643 Linux RUN", "45234 Linux RUN", "3535 Linux DONE",
"93756387 Linux DONE"
);

foreach my $re (@list1) {
my @found = grep /$re/, @list2;
print "@found\n" if @found;
}

__END__
 
T

Tim McDaniel

I have 2 lists.

As an example:
@list1 = (1234, 345638, 3535, 93756387);
@list2 = ("375539 Linux DONE", "1234 Linux DONE", "345638 Linux EXIT", "6384643 Linux RUN", "45234 Linux
RUN", "3535 Linux DONE", "93756387 Linux DONE");

I need to print out the list of elements in list2 where the first number part of the string does NOT
exist in list1.

I need to get a list3 from list2 where list3 looks like below
@list3 = ("375539 Linux DONE", "6384643 Linux RUN", "45234 Linux RUN");

None of the above first number parts in list3 exist in list1, which is how I want it to be.

What would be the simplest way of doing this in Perl?

The better sort of reply would note that this might be a "do my
homework for me" question and would ask what you've tried already.

So what have you tried already? Or what have you thought about and
not known how to do?

I'll be kind enough, or unkind enough (in that, if it's a class,
someone providing you with a solution is hurting your learning), to
suggest that you consider a hash table:
- hash1, with key = each element of @list1 and value = 1 (the value
need not be used so it doesn't matter)
Then go through each element of @list2, separate out the number at the
start of the element, and see whether it's in %hash1.
 
G

gamo

El 06/05/14 05:17, Udaykumar Kunapuli escribió:
Hi,

I have 2 lists.

As an example:
@list1 = (1234, 345638, 3535, 93756387);
@list2 = ("375539 Linux DONE", "1234 Linux DONE", "345638 Linux EXIT", "6384643 Linux RUN",

"45234 Linux RUN", "3535 Linux DONE", "93756387 Linux DONE");
I need to print out the list of elements in list2 where the first number part of the string does NOT exist in list1.

I need to get a list3 from list2 where list3 looks like below
@list3 = ("375539 Linux DONE", "6384643 Linux RUN", "45234 Linux RUN");

None of the above first number parts in list3 exist in list1, which is how I want it to be.

What would be the simplest way of doing this in Perl?

Thanks,
Uday

for $j (@list2){
$j =~ /(\d+)\s/;
$n = $1; # extract the number
$ok=1;
for $i (@list1){
if ($i == $n){
$ok =0;
last;
}
}
if ($ok==1){
push @list3, $j;
}
}

You ask for the simplest way.
 
I

ilovelinux

Maybe not the simplest, but to avoid programming a nested loop: create a
regular expression of the numbers in @list1 and grep @list2 for that RE.

my $re = join("|", map { quotemeta $_ } @list1);
my @list3 = grep { !/$re/ } @list2;
 
G

gamo

El 06/05/14 10:08, Jürgen Exner escribió:
The simplest way is to use "exists" instead of that flag in a nested
loop.

jue

Ok, let's go:

for $i (@list1){
$h{$i}=1;
}

for $j (@list2){
$j =~ /(\d+)\s/;
$n = $1;
unless (defined $h{$n}){
push @list3, $j;
}
}
%h = ();
 
R

Rainer Weikusat

gamo said:
El 06/05/14 10:08, Jürgen Exner escribió:[...]
The simplest way is to use "exists" instead of that flag in a nested
loop.

jue

Ok, let's go:

for $i (@list1){
$h{$i}=1;
}

for $j (@list2){
$j =~ /(\d+)\s/;
$n = $1;
unless (defined $h{$n}){
push @list3, $j;
}
}
%h = ();

This can be simplified somewhat with map and grep:

%filter = map { $_, 1 } @list1;
@list3 = grep { /^(\S+)/, !$filter{$1}; } @list2;

The grep expression could also be written as

!$first{(/^(\S+)/)[0]}

I'm unsure if this should be considered a good or a bad idea.
 
M

Manfred Lotz

Hi,

I have 2 lists.

As an example:
@list1 = (1234, 345638, 3535, 93756387);
@list2 = ("375539 Linux DONE", "1234 Linux DONE", "345638 Linux
EXIT", "6384643 Linux RUN", "45234 Linux RUN", "3535 Linux DONE",
"93756387 Linux DONE");

I need to print out the list of elements in list2 where the first
number part of the string does NOT exist in list1.

I need to get a list3 from list2 where list3 looks like below
@list3 = ("375539 Linux DONE", "6384643 Linux RUN", "45234 Linux
RUN");

None of the above first number parts in list3 exist in list1, which
is how I want it to be.

What would be the simplest way of doing this in Perl?

I would do it this way. If @list1 is really large one should perhaps
think twice.

<---------------------------snip------------------------------>
#! /usr/bin/perl

use strict;
use warnings;

my @list1 = (1234, 345638, 3535, 93756387);
my @list2 = ("375539 Linux DONE", "1234 Linux DONE", "345638 Linux
EXIT", "6384643 Linux RUN", "45234 Linux RUN", "3535 Linux DONE",
"93756387 Linux DONE");


my %hash = map { $_ => 1 } @list1;
my @list3;

foreach my $li ( @list2 ) {
my @words = split /\s+/,$li;
if ( not defined $hash{"$words[0]"} ) {
push @list3, $li;
}
}

foreach my $li ( @list3 ) {
print "$li\n";
}

<---------------------------snap------------------------------>
 
T

Tim McDaniel

for $i (@list1){
$h{$i}=1;
}

People should
use strict;
use warnings;
and declare all variables.

People have posted two ways to convert a list to a hash in which the
indexes are the members of the list. Here's the version I usually use:

@h{@list1} = (1) x @list1;
 
T

Tim McDaniel

People have posted two ways to convert a list to a hash in which the
indexes are the members of the list.

Sorry -- two people, both using something of the form
%hash1 = map { $_ => 1 } @list1;
 
R

Rainer Weikusat

People should
use strict;
use warnings;
and declare all variables.

People have posted two ways to convert a list to a hash in which the
indexes are the members of the list. Here's the version I usually use:

@h{@list1} = (1) x @list1;

Two similar other ways would be

++$_ for @h{@list}

s///1/ for @h{@list}

If one is willing to test for 'existence' instead of truth, any
expression can be used in front of the find, eg

// for @h{@list}

or

1 for @h{@list}

Actually, any operator which modifies its operand will do for this case, eg,

++@h{@list}
 
T

Tim McDaniel

If one is willing to test for 'existence' instead of truth, any
expression can be used in front of the find, eg ....
1 for @h{@list}

Actually, any operator which modifies its operand will do for this case, eg,

++@h{@list}

$ perl -e 'use strict; use warnings; use Data::Dumper; my @list = (17, 19, 23); my %h; ++@h{@list}; print Dumper(\%h), "\n"'
$VAR1 = {
'23' => 1,
'19' => undef,
'17' => undef
};
$ perl -e 'use strict; use warnings; use Data::Dumper; my @list = (17, 19, 23); my %h; 0 for @h{@list}; print Dumper(\%h), "\n"'
$VAR1 = {
'23' => undef,
'19' => undef,
'17' => undef
};

OK, I don't get it. What's going on here? I don't think it could be
autovivication eo nomine.
 
R

Rainer Weikusat

$ perl -e 'use strict; use warnings; use Data::Dumper; my @list = (17, 19, 23); my %h; ++@h{@list}; print Dumper(\%h), "\n"'
$VAR1 = {
'23' => 1,
'19' => undef,
'17' => undef
};
$ perl -e 'use strict; use warnings; use Data::Dumper; my @list = (17, 19, 23); my %h; 0 for @h{@list}; print Dumper(\%h), "\n"'
$VAR1 = {
'23' => undef,
'19' => undef,
'17' => undef
};

OK, I don't get it. What's going on here? I don't think it could be
autovivication eo nomine.

'Autovivification because of lvalue context', see pp_hslice in pp.c.
 
D

Dr.Ruud

I have 2 lists.

As an example:
@list1 = (1234, 345638, 3535, 93756387);
@list2 = ("375539 Linux DONE", "1234 Linux DONE", "345638 Linux EXIT", "6384643 Linux RUN", "45234 Linux RUN", "3535 Linux DONE", "93756387 Linux DONE");

I need to print out the list of elements in list2 where the first number part of the string does NOT exist in list1.

I need to get a list3 from list2 where list3 looks like below
@list3 = ("375539 Linux DONE", "6384643 Linux RUN", "45234 Linux RUN");

None of the above first number parts in list3 exist in list1, which is how I want it to be.

What would be the simplest way of doing this in Perl?

There are many ways, for example:

perl -Mstrict -wE'
my @list1 = (1234, 345638, 3535, 93756387);
my @list2 = ("375539 Linux DONE", "1234 Linux DONE"
, "345638 Linux EXIT", "6384643 Linux RUN", "45234 Linux RUN"
, "3535 Linux DONE", "93756387 Linux DONE");
my $re = join "|", @list1;
my @list3 = grep !/^(?:$re)\b/, @list2;
'
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,920
Messages
2,570,038
Members
46,449
Latest member
onedumbsquirrel

Latest Threads

Top