How to prevent duplicated entry in array of the hash

C

Cyrus

Hi folks,
I'm new in this group, I would like to ask all of the Perl experts out
there, if any one knows how to prevent a duplicated entry in array of
the hash: here is what I need to do. The script periodically check for
disk status if there is an error it adds it to array of the hash with
keys & value, what I need is before it push/append it to the array of
the hash it check to see if the key & value exists if not then
push/append it else do other stuff or next
Thanks in advance & hop I can get an answer from one of you guys..
Cheers

Here is a portion of the code:
my $sh = $c->show_disk();
foreach my $sys (@sys_arry) {
foreach my $el (@$sh) {
if ($el->{'status'} ne "OK")
{
# Here I know I should check to see if the keys & value exits
but don't know how!!
push @DiskErr, {sys=>$sys, disk=>$el->{'id'},
status=>$el->{'status'}};
} else
{
print "$sys: Status OK\n";
}
}
}
 
C

Cyrus

One more thing to add is a system has multiple disks, & I have more
than 200 systems to check for system, disk & disk status. to make it
more clear if script finds an error say on system-X with disk 2 &
status No-In-Service it notify user and go to the next system, when it
hits same system again it checks to see if this is a same system if so
if this is a same disk if this is same system & same disk & same status
then don't notify user simply go to the next till the status of the
disk gets change when it hits that system again!
Cyrus
Jim said:
Cyrus said:
Hi folks,
I'm new in this group, I would like to ask all of the Perl experts out
there, if any one knows how to prevent a duplicated entry in array of
the hash: here is what I need to do. The script periodically check for
disk status if there is an error it adds it to array of the hash with
keys & value, what I need is before it push/append it to the array of
the hash it check to see if the key & value exists if not then
push/append it else do other stuff or next
Thanks in advance & hop I can get an answer from one of you guys..
Cheers

Use a hash to record saved entries. It is not clear what should not be
duplicated in your program below. Just $sys, or the $sys/$el->{'id}
combination.

Assuming it is just $sys (untested):
Here is a portion of the code:

my %bad;
my $sh = $c->show_disk();
foreach my $sys (@sys_arry) {
foreach my $el (@$sh) {
if ($el->{'status'} ne "OK")
{
# Here I know I should check to see if the keys & value exits
but don't know how!!

if( ! exists $bad{$sys} ) {
push @DiskErr, {sys=>$sys, disk=>$el->{'id'},
status=>$el->{'status'}};

$bad{$sys} = $status; # any value, even 1
 
C

Cyrus

Sorry folks for muliple posting, as I said before I'm new & it won't
happen again..
cheers
Jim said:
Please do not top-post in this newsgroup. Try to put your responses
below that to which you are responding. And please trim irrelevant
material. Thanks. (Top-posting has been fixed.)


[program snipped]

One more thing to add is a system has multiple disks, & I have more
than 200 systems to check for system, disk & disk status. to make it
more clear if script finds an error say on system-X with disk 2 &
status No-In-Service it notify user and go to the next system, when it
hits same system again it checks to see if this is a same system if so
if this is a same disk if this is same system & same disk & same status
then don't notify user simply go to the next till the status of the
disk gets change when it hits that system again!

How are you finding these systems? Why will you potentially be checking
a system/disk more than once? What about just saving up all of the bad
status indications, putting them into one e-mail, and sending that.
That way, duplicates will not be such a problem. (Not much Perl content
in this post. Sorry.)
 
C

Cyrus

Q: How are you finding these systems?
A: ssh to the system
Q: Why will you potentially be checking a system/disk more than once?
A: Disk might go out of commission .
Q: What about just saving up all of the bad status indications, putting
them into one e-mail, and sending that.That way, duplicates will not be
such a problem.
A: That's What I'm doing, the problem is I don't want to send muliple
email on the same system, just to make a note here all script check
same systems over and over gain.

Sorry folks for muliple posting, as I said before I'm new & it won't
happen again..
cheers
Jim said:
Please do not top-post in this newsgroup. Try to put your responses
below that to which you are responding. And please trim irrelevant
material. Thanks. (Top-posting has been fixed.)

Cyrus said:
Jim Gibson wrote:
Hi folks,
I'm new in this group, I would like to ask all of the Perl experts out
there, if any one knows how to prevent a duplicated entry in array of
the hash: here is what I need to do. The script periodically check for
disk status if there is an error it adds it to array of the hash with
keys & value, what I need is before it push/append it to the array of
the hash it check to see if the key & value exists if not then
push/append it else do other stuff or next
Thanks in advance & hop I can get an answer from one of you guys..
Cheers

Use a hash to record saved entries. It is not clear what should not be
duplicated in your program below. Just $sys, or the $sys/$el->{'id}
combination.

[program snipped]

One more thing to add is a system has multiple disks, & I have more
than 200 systems to check for system, disk & disk status. to make it
more clear if script finds an error say on system-X with disk 2 &
status No-In-Service it notify user and go to the next system, when it
hits same system again it checks to see if this is a same system if so
if this is a same disk if this is same system & same disk & same status
then don't notify user simply go to the next till the status of the
disk gets change when it hits that system again!

How are you finding these systems? Why will you potentially be checking
a system/disk more than once? What about just saving up all of the bad
status indications, putting them into one e-mail, and sending that.
That way, duplicates will not be such a problem. (Not much Perl content
in this post. Sorry.)
 
K

Keith Keller

Q: Why are you *still* top-posting, even when you've been asked
not to do so?
A: Either I'm not paying enough attention, or I don't actually
want help.

On the off-chance that you do decide to pay attention (and if you
don't, watch more people killfile you):

Q: What about just saving up all of the bad status indications, putting
them into one e-mail, and sending that.That way, duplicates will not be
such a problem.
A: That's What I'm doing, the problem is I don't want to send muliple
email on the same system, just to make a note here all script check
same systems over and over gain.

If you'll be re-running this script, and want the script to be
able to reference past data, you need to store the previous data
somewhere, either on disk or in a database. For the former, read
perldoc -q persistent ; for the latter, you can start with the
DBI docs (though there's a pretty steep learning curve, especially
if you don't have database experience).

--keith
 
M

Mumia W. (on aioe)

Hi folks,
I'm new in this group, I would like to ask all of the Perl experts out
there, if any one knows how to prevent a duplicated entry in array of
the hash: here is what I need to do. The script periodically check for
disk status if there is an error it adds it to array of the hash with
keys & value, what I need is before it push/append it to the array of
the hash it check to see if the key & value exists if not then
push/append it else do other stuff or next
Thanks in advance & hop I can get an answer from one of you guys..
Cheers

Here is a portion of the code:
my $sh = $c->show_disk();

my %DiskErr;
foreach my $sys (@sys_arry) {
foreach my $el (@$sh) {
if ($el->{'status'} ne "OK")
{
# Here I know I should check to see if the keys & value exits
but don't know how!!
push @DiskErr, {sys=>$sys, disk=>$el->{'id'},
status=>$el->{'status'}};

Replace the above with this:

push @{$DiskErr{$sys}}, { sys => $sys, disk => $el->{'id'}, status =>
$el->{'status'} };

That autovivifies a hash entry for $DiskErr{$sys} that is an array
reference. The array then has an anonymous hash pushed onto it.

Note, the code is untested.
} else
{
print "$sys: Status OK\n";
}
}
}

By their natures, hashes do not allow duplicate keys, so if you use a
hash, you don't have to check for duplicates.

Read the documentation:
perldoc perlref
perldoc perldsc
 
C

Cyrus

Thanks for the reply, I tried that before but didn't wotk for me I need
to check if there is an existing entry in the hash of the array for
sys, disk & status witout goiing through the nested for loops!
 
C

Cyrus

Keith I do reply to the message, do I need to use other option, please
walk me through this so it won't happen again..
cyrus
 
D

DJ Stunks

Cyrus said:
Keith I do reply to the message, do I need to use other option, please
walk me through this so it won't happen again..

you're top posting, that means you're writing your response on top, and
quoting (in full) the replies beneath it.

Stop doing that.

Instead, snip everything from the replies except the attribution (who
said it) and some relevant context, and post your response underneath
so that if one reads from top to bottom (like the english language
works) the complete message makes sense.

-jp
 
C

Cyrus

Jürgen Exner said:
Got what?
Are you guys polling my leg :-( I was replying back to Keith concern!
anyway I haven't got any solution for the problem I'm facing any body
out there can help me on this or just call it quit?
 
C

Cyrus

An easier approach is to take advantage of the fact that hash keys are
unique - in fact, whenever I hear the words "unique" or "duplicate" with
respect to managing entries in a collection, I immediately think of a
hash. Example:

# Hash, and key to add
my %test_hash;
my $new_value = 'foo';

# Just add it - dups are eliminated automatically because it's a hash
$test_hash{$new_value} = 0;

sherm--

Thanks... below is the out puthere is output from Dumper, & here is my
appand to hash of array.
push @{$DiskErr{$sys}}, {disk => [$el->{'id'}], status =>
[$el->{'status'}] };

As you can see there is duplicated entries for disk 5 and a ststem can
have up 20 disks that's why I used above push! any idea how to prevent
a duplicate entry?
The DiskErr is $VAR1 = {
'BR5500' => [
{
'disk' => [
'5'
],
'status' => [
'NOT-IN-SERVICE'
]
},
{
'disk' => [
'5'
],
'status' => [
'NOT-IN-SERVICE'
]
},
{
disk' => [
'2'
],
'status' => [
'NOT-IN-SERVICE'
]
},

],
 
C

Cyrus

$DiskErr->{$sys}->{$el->{'id'}} = { status => $el->{'status'} };

That will give you a data structure that looks like this:

{
'BR5500' => {
'5' => {
'status' => 'NOT-IN-SERVICE',
}
},
}
Thank you so much Sherm, I will use the above per your request as one
disk can have only one status at a time...before I rest my case How do
I access disk , is it sompthing like this:

my $diskStatus = $DiskErr->->{$sys}->{$el->{'id'}} ;

Again thank you & you are my hero & life saver....Oh by the way How am
I doing with reply with toping :)
 
C

Cyrus

Like I said, I'd use a hash, with the disk number as the key:
$DiskErr->{$sys}->{$el->{'id'}} = { status => $el->{'status'} };
I get an error: Global symbol "$DiskErr" requires explicit package name
at....
I declare that as: my %DiskErr;
 
C

Cyrus

I declare that as: my %DiskErr;
Sorry 'bout that. Your original code didn't declare it, so I figured were
declaring it somewhere else.

sherm--

Still getting error even after declaring my %DiskErr;
any idea..
Global symbol "$DiskErr" requires explicit package name a
 
P

Paul Lalli

Sherm said:
You're declaring it, but not in the same scope in which you're using it.

No, he's not declaring it. He's declaring %DiskErr, when he's using
$DiskErr. Two completely unrelated variables.

Paul Lalli
 
C

Cyrus

You're declaring it, but not in the same scope in which you're using it.

There was extra ->, it should be like below I fixed it...thanks a lot:
Coorect: $DiskErr{$sys}->{$el->{'id'}} = { status => $el->{'status'}
};
WRONG: $DiskErr->{$sys}->{$el->{'id'}} = { status => $el->{'status'}
};

Cheers & Have Great Holiday...
 
T

Tad McClellan

Cyrus said:
Still getting error even after declaring my %DiskErr;
any idea..
Global symbol "$DiskErr" requires explicit package name a


Don't declare %DiskErr (a hash).

Instead declare $DiskErr (a scalar).
 

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

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top