CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
Matching an item in an array

 



HR
Novice

Oct 15, 2001, 6:24 PM

Post #1 of 14 (2731 views)
Matching an item in an array Can't Post

Trying to write a simple subroutine for a message board. Want to be able to enter problem users names in an array and prevent them from posting. Here is what I have so far but it is not working. Am I doing something wrong when I compare the user name to the items in the array? The user name it is comparing this to is stored in a scalar called $last.

@bannedlist = ("Tom", "Dick", "Harry");

sub name_check {

foreach $banned (@bannedlist) {
if ($banned =~ /$last/) {
&dupe_error;
unlock($lockingdir);
&exit;
}
}
}



S_Shrum
User

Oct 15, 2001, 9:21 PM

Post #2 of 14 (2729 views)
Re: Matching an item in an array [In reply to] Can't Post

Use the EXISTS function. If you have a single element array, which by your message is what you have defined, the code would be (out of the book / untested):


Code
if ( $last exists $bannedlist[0] ) { 
...
...code here to redirect to banned page
...
} else {
...
...code here to allow input to database
...
}

I need to code something like this later so if I get to it tonight, I will revise my post if I find the above is formatted incorrectly.

Sean Shrum
sean@shrum.net
www.shrum.net


mhx
Enthusiast / Moderator

Oct 15, 2001, 10:42 PM

Post #3 of 14 (2726 views)
Re: Matching an item in an array [In reply to] Can't Post

I don't know why this isn't working for you. The following example code worked when I ran it:

Code
#!/bin/perl -w 

@bannedlist = ("Tom", "Dick", "Harry");
$last = "Dick";

name_check();

sub name_check {
foreach $banned (@bannedlist) {
if ($banned =~ /$last/) {
print "banned $last!\n";
}
}
}

However, you should try not to use a regex match to compare strings. In the above case, $banned="Dicky" and $last="Dick" would ban Dick if you only wanted to ban Dicky. So you should rather use eq or put /^anchors$/ around your regex. In combination with Perl's grep function, this would be:

Code
#!/bin/perl -w 

@bannedlist = ("Tom", "Dick", "Harry");
$last = "Dick";

name_check();

sub name_check {
if( grep /^$last$/, @bannedlist ) {
print "banned $last!\n";
}
}

Hope this helps.

-- Marcus


Code
s$$ab21b8d15c3d97bd6317286d$;$"=547269736;split'i',join$,,map{chr(($*+= 
($">>=1)&1?-hex:hex)+0140)}/./g;$"=chr$";s;.;\u$&;for@_[0,2];print"@_,"



HR
Novice

Oct 16, 2001, 3:20 PM

Post #4 of 14 (2717 views)
Re: Matching an item in an array [In reply to] Can't Post

Thanks!

The exists solution gave me an internal server error.

The grep solution works like a charm.

The original code I came up with doesn't look like it should have anything wrong with it but the script acts like it doesn't even exist and lets posts right through. If I comment out the if part and just leave the error message and exit it quits like it should so it's not a typo skipping the sub or anything, can't figure it out.



mhx
Enthusiast / Moderator

Oct 16, 2001, 8:40 PM

Post #5 of 14 (2715 views)
Re: Matching an item in an array [In reply to] Can't Post


In Reply To
The exists solution gave me an internal server error.

I'm not surprised. You can't use exists that way...

-- Marcus


Code
s$$ab21b8d15c3d97bd6317286d$;$"=547269736;split'i',join$,,map{chr(($*+= 
($">>=1)&1?-hex:hex)+0140)}/./g;$"=chr$";s;.;\u$&;for@_[0,2];print"@_,"



S_Shrum
User

Oct 17, 2001, 1:40 AM

Post #6 of 14 (2709 views)
Re: Matching an item in an array [In reply to] Can't Post

My bad....I was getting ahead of myself. But while we are on the topic, I have a similar question along the same vein...

I am going to write a DB field value in/decrementer (basically it will read a flatfile DB into an array). The parameters will be (so far):

in=<field to search for key value>
for=<key value>
increment=<field to get value from and increment>
decrement=<field to get value from and decrement>

< Figured if I was going to increment I might need to decrement later. >

I need to be able to not only know that the element exists in the array, but I need to know the cell row.

Short of going through the column of the entire array one cell at a time until GREP returns true on a cell value, is there a faster way? Would it be advantagous to run GREP over the entire array as a pre-cursory check before running through the entine array or would that just double the amount of time that it takes?

Once again: Sorry for the confusion earlier. Just a little to eager to help.

Sean Shrum
sean@shrum.net
www.shrum.net


mhx
Enthusiast / Moderator

Oct 17, 2001, 5:28 AM

Post #7 of 14 (2705 views)
Re: Matching an item in an array [In reply to] Can't Post

I don't quite get the data structure you are using. I guess it's an array of arrays or an array of hashes. However, you could additionally store the cell row within your data structure (although this is redundancy if you're using an array), but if you create a hash table while filling the array that holds references to each array element, you can access each array element via the hash and use the hash key to check for existence.
I hope you can get what I mean from that brief description. If you don't know what I'm talking about let me know so I can think about an example. (I can't think right now 'cos I'm in a hurry... ;-)

-- Marcus


Code
s$$ab21b8d15c3d97bd6317286d$;$"=547269736;split'i',join$,,map{chr(($*+= 
($">>=1)&1?-hex:hex)+0140)}/./g;$"=chr$";s;.;\u$&;for@_[0,2];print"@_,"



S_Shrum
User

Oct 17, 2001, 2:22 PM

Post #8 of 14 (2695 views)
Re: Matching an item in an array [In reply to] Can't Post

um...okay.

Here's the deal. You are correct in that it is an array of arrays. The data file will look like:

[FILE: links.dat]


Code
Area|Title|URL|Description|Hits 
Programming|Perl Guru|forums.perlguru.com|Forum for Perl questions|0
Programming|PerlDoc|www.perldoc..com|Online documentation for Per|0
Music|Sting|www.sting.com|Sting's Official Homepage|0

Granted, the original file is a bit bigger than this but this an example of what I am working with.

I load the data into a multidim array (I know, they don't REALLY exist), using split(), like below (with parameter passing)


Code
open (DB, "$rootPath$input{'file'}") or die "$err_openlocalfile"; 
while (<DB>) {
chomp $_;
tr/\r//d;
push @dump, [ split(/\Q$input{'seperator'}\E/, $_) ];
}
close(DB);

The concept I have is that I will search on a field (IN parameter) that contains a unique entry (URL), search for the FOR parameter (www.perldoc.com) and increment the value field defined in the INCREMENT parameter (Hits).

Is there a faster way to get the process done other than the standard for loop to find the entry; granted the loop count variable will give me the row number.

Sean Shrum
sean@shrum.net
www.shrum.net


mhx
Enthusiast / Moderator

Oct 17, 2001, 9:35 PM

Post #9 of 14 (2691 views)
Re: Matching an item in an array [In reply to] Can't Post

Sorry, but I still don't get it. Must be me... Crazy

Could you explain the following in a bit more detail:

In Reply To
The concept I have is that I will search on a field (IN parameter) that contains a unique entry (URL), search for the FOR parameter (www.perldoc.com) and increment the value field defined in the INCREMENT parameter (Hits).

Thanks,
Marcus


Code
s$$ab21b8d15c3d97bd6317286d$;$"=547269736;split'i',join$,,map{chr(($*+= 
($">>=1)&1?-hex:hex)+0140)}/./g;$"=chr$";s;.;\u$&;for@_[0,2];print"@_,"



S_Shrum
User

Oct 17, 2001, 10:58 PM

Post #10 of 14 (2689 views)
Re: Matching an item in an array [In reply to] Can't Post

Here's a link to the script that's about 90% done.

All the concepts are written in but I am currently having problems with the grep on line 217 ( and consequently will have the same problem on line 219 ). I was trying to use your prior code snippet using grep. Any ideas? Blush

To restate: I was wondering if there was a faster way to process through the array of arrays to increment a cell within a row of the array (besides what I currently have).

script: http://www.shrum.net/db_increment.pl.txt
data: http://www.shrum.net/test.dat

Sean Shrum
sean@shrum.net
www.shrum.net


S_Shrum
User

Oct 18, 2001, 1:11 AM

Post #11 of 14 (2687 views)
Re: Matching an item in an array [In reply to] Can't Post

I tried the "eq" instead of "grep" and that worked so don't worry about that.

I got the script working and updated the db_increment.pl.txt file to the newer version of the script. The links in my prior message are still valid.

Take a look at the loop. While I think this is the correct way to do it, I am looking to optimize it (if possible).

Sean Shrum
sean@shrum.net
www.shrum.net


mhx
Enthusiast / Moderator

Oct 20, 2001, 4:22 AM

Post #12 of 14 (2664 views)
Re: Matching an item in an array [In reply to] Can't Post

Sorry this took so long but I've been quite busy over the last few days. However, I've attached a version of your script with my comments. I've also attached a quick hack at the bottom to give you an idea of possible speed optimizations. I guess (read: I'm pretty sure) this can be improved even further.

-- Marcus


Code
s$$ab21b8d15c3d97bd6317286d$;$"=547269736;split'i',join$,,map{chr(($*+= 
($">>=1)&1?-hex:hex)+0140)}/./g;$"=chr$";s;.;\u$&;for@_[0,2];print"@_,"



S_Shrum
User

Oct 20, 2001, 11:16 PM

Post #13 of 14 (2657 views)
Re: Matching an item in an array [In reply to] Can't Post

This is great! I am looking over your additions...there are some functions here I have never used before so I am looking these up now to get a better understanding of them.

Thanks again.

Sean Shrum
sean@shrum.net
www.shrum.net


S_Shrum
User

Oct 20, 2001, 11:48 PM

Post #14 of 14 (2657 views)
Re: Matching an item in an array [In reply to] Can't Post

Sorry for the double post...but just in case someone comes along and wonders...

I have tried the DBI. I installed the AnyData DBD and ever created a simple interface script that allows me to output the data from any source to a HTML table. However, I found that some of the functions in the DBD were not working and short of having to learn everything about the format that the DBD was attempting and make the corrections myself, I decided that something like this would be faster and easier to maintain and install (being that it's just one file as opposed to installing the DBI and DBD's).

Being a beginner to Perl, I am simply wetting my feet. I have the O Reilly "Programming the Perl DBI" but this is a bit much for me at this stage. As I stated before, there are a number of functions that I would like to be more comfortable with before I start hacking into the DBI.

Sean Shrum
sean@shrum.net
www.shrum.net

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives