A little help on perl hashes..

C

clearguy02

Hi all,

I am struggling with the below puzzle:

Here is the contents of a file, c:\test.txt

============================================================
user id name uid mid

jsmiths john 00206251 00207609
jcarter joseph 00207609 00220458
mstella mary 00202227 00207609
cgoldberg cindy 00220458 00202003
mshiva murthy 00224981 00207609
hwatson henry 00202003 00201869
=============================================================


jcarter is the manager of jsmiths, mstella and mshiva;
cgoldberg is the manager of jcarter;
hwatson is the manager of cgoldberg;

In the output file, I need to replace the mid with the manager id as
follows. And the topmost manager (hwatson) can remain with his id.

================================================
user id name manager id

jsmiths john jcarter
jcarter joseph cgoldberg
mstella mary jcarter
cgoldberg cindy hwatson
mshiva murthy jcarter
hwatson henry hwatson
=================================================

I am uisng the hases and arrays and not getting the desired output.

Can some one help me out here?

Thanks,
JC
 
C

clearguy02

Hi all,

I am struggling with the below puzzle:

Here is the contents of a file, c:\test.txt

============================================================
user id name uid mid

jsmiths john 00206251 00207609
jcarter joseph 00207609 00220458
mstella mary 00202227 00207609
cgoldberg cindy 00220458 00202003
mshiva murthy 00224981 00207609
hwatson henry 00202003 00201869
=============================================================

jcarter is the manager of jsmiths, mstella and mshiva;
cgoldberg is the manager of jcarter;
hwatson is the manager of cgoldberg;

In the output file, I need to replace the mid with the manager id as
follows. And the topmost manager (hwatson) can remain with his id.

================================================
user id name manager id

jsmiths john jcarter
jcarter joseph cgoldberg
mstella mary jcarter
cgoldberg cindy hwatson
mshiva murthy jcarter
hwatson henry hwatson
=================================================

I am uisng the hases and arrays and not getting the desired output.

Can some one help me out here?

Thanks,
JC

Can some one take a look at it? :)

JC
 
B

Brian McCauley

Can some one take a look at it? :)

No, we can't look at what we can't see.

I'm guessing you used the "attach" mechanism to attach your code and
it got stripped somewhere.

Paste your code inline - but first see the posting guidelines for
things you should do first to avoid wasting the time of people who are
trying to help you.
 
C

clearguy02

After you've posted "it" three times?

Um... no. Learn some manners and maybe I'll help next time.

sherm--

I am storing the whole file into an array, @array. Then I am splititng
each line in the array with split function and storing the each field
as $array[0], $array[1], $array[2), and $array[3]; Then I am looping
the file again to compare $array[3] and $array[0] and replace the
$array[3] with with $array[0] appropriately.. now I am hitting a
problem in thic comarison mechanism.. can some one help with me with a
better algorithm/code?

Thanks,
JC
 
Q

QoS

After you've posted "it" three times?

Um... no. Learn some manners and maybe I'll help next time.

sherm--

I am storing the whole file into an array, @array. Then I am splititng
each line in the array with split function and storing the each field
as $array[0], $array[1], $array[2), and $array[3]; Then I am looping
the file again to compare $array[3] and $array[0] and replace the
$array[3] with with $array[0] appropriately.. now I am hitting a
problem in thic comarison mechanism.. can some one help with me with a
better algorithm/code?

Thanks,
JC

#You should probably do something while storing the file to the array.
while (<FILE1>) {
my $line = $_;

#Like splitting the line and storing its elements in an array
my @lineArray = split (/\s+/, $line); #Or split as desired

#Ok, replace the fourth item in the array with the first item
#if some condition is true; elaborate more on what you need here.
if ($lineArray[3] < $lineArray[0]) {
$lineArray[3] = $lineArray[0];
}
}
 
C

clearguy02

I am storing the whole file into an array, @array. Then I am splititng
each line in the array with split function and storing the each field
as $array[0], $array[1], $array[2), and $array[3]; Then I am looping
the file again to compare $array[3] and $array[0] and replace the
$array[3] with with $array[0] appropriately.. now I am hitting a
problem in thic comarison mechanism.. can some one help with me with a
better algorithm/code?
Thanks,
JC

#You should probably do something while storing the file to the array.
while (<FILE1>) {
my $line = $_;

#Like splitting the line and storing its elements in an array
my @lineArray = split (/\s+/, $line); #Or split as desired

#Ok, replace the fourth item in the array with the first item
#if some condition is true; elaborate more on what you need here.
if ($lineArray[3] < $lineArray[0]) {
$lineArray[3] = $lineArray[0];
}

}

I have been successful until the first part (until splitting and
storing each field of each line.. but the problem is to throw the
comparison part.. I first need loop through the list to make sure that
so and so mid belong to a user id and then replace the mid with the
user id. Here I am trying to use the key, values pair, but not quite
successful.. Any help?

JC
 
C

clearguy02

I am storing the whole file into an array, @array. Then I am splititng
each line in the array with split function and storing the each field
as $array[0], $array[1], $array[2), and $array[3]; Then I am looping
the file again to compare $array[3] and $array[0] and replace the
$array[3] with with $array[0] appropriately.. now I am hitting a
problem in thic comarison mechanism.. can some one help with me with a
better algorithm/code?
Thanks,
JC

#You should probably do something while storing the file to the array.
while (<FILE1>) {
my $line = $_;

#Like splitting the line and storing its elements in an array
my @lineArray = split (/\s+/, $line); #Or split as desired

#Ok, replace the fourth item in the array with the first item
#if some condition is true; elaborate more on what you need here.
if ($lineArray[3] < $lineArray[0]) {
$lineArray[3] = $lineArray[0];
}



}- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -

Forgot to add my code:
====================================
while (<DATA>)
{
$line = $_;
@lineArray = split (/\s+/, $line);

if ($lineArray[3] == $lineArray[2])
{
s/$lineArray[3]/$lineArray[0]/g;
}
print "$lineArray[0]\t\t$lineArray[1]\t\t$lineArray[3]\n";
}
==================================

Can some one help me here?

Thanks in advance,
JC
}
 
C

clearguy02

(e-mail address removed) wrote in message-id: <8186189c-6041-4f47-8656-b58b20886...@s36g2000prg.googlegroups.com>
(e-mail address removed) writes:
Can some one take a look at it? :)
After you've posted "it" three times?
Um... no. Learn some manners and maybe I'll help next time.
sherm--
--
WV News, Blogging, and Discussion:http://wv-www.com
Cocoa programming in Perl:http://camelbones.sourceforge.net
I am storing the whole file into an array, @array. Then I am splititng
each line in the array with split function and storing the each field
as $array[0], $array[1], $array[2), and $array[3]; Then I am looping
the file again to compare $array[3] and $array[0] and replace the
$array[3] with with $array[0] appropriately.. now I am hitting a
problem in thic comarison mechanism.. can some one help with me with a
better algorithm/code?
Thanks,
JC
#You should probably do something while storing the file to the array.
while (<FILE1>) {
my $line = $_;
#Like splitting the line and storing its elements in an array
my @lineArray = split (/\s+/, $line); #Or split as desired
#Ok, replace the fourth item in the array with the first item
#if some condition is true; elaborate more on what you need here.
if ($lineArray[3] < $lineArray[0]) {
$lineArray[3] = $lineArray[0];
}
}- Hide quoted text -
- Show quoted text -- Hide quoted text -
- Show quoted text -

Forgot to add my code:
====================================
while (<DATA>)
{
$line = $_;
@lineArray = split (/\s+/, $line);

if ($lineArray[3] == $lineArray[2])
{
s/$lineArray[3]/$lineArray[0]/g;
}
print "$lineArray[0]\t\t$lineArray[1]\t\t$lineArray[3]\n";}

==================================

Can some one help me here?

Thanks in advance,
JC



}- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -

Hi all,

I am still looking our the help.. Can some kindly take a look at it?

Thanks,
JC
 
B

Ben Morrow

Quoth (e-mail address removed):
On Nov 22, 8:00 am, (e-mail address removed) wrote:

I am still looking our the help.. Can some kindly take a look at it?

Being a pain doesn't often lead to useful help on Usenet. Responding to
your own post after 12 hours simply to ask again and quoting Google's
rubbish both count as being a pain, especially when you've been warned
you're being rude.

Ben
 
C

clearguy02

Quoth (e-mail address removed):







Being a pain doesn't often lead to useful help on Usenet. Responding to
your own post after 12 hours simply to ask again and quoting Google's
rubbish both count as being a pain, especially when you've been warned
you're being rude.

Ben- Hide quoted text -

- Show quoted text -

Hi Ben,

When I was asked to post my code, I did it.. If you don't want to
help.. pl. kindly stay away. Pl. understand that I am stuck with an
issue and that I am not fooling around here. I have clearly told what
the issue is, what I have done and I am seeking out for some help
here.
 
U

Uri Guttman

c> When I was asked to post my code, I did it.. If you don't want to
c> help.. pl. kindly stay away. Pl. understand that I am stuck with an
c> issue and that I am not fooling around here. I have clearly told what
c> the issue is, what I have done and I am seeking out for some help
c> here.

did you pay for your service here? since you didn't you don't have a
right to expect anything from usenet. you just post code and ask for
help and shut up about it. this is a place to discuss perl issues and if
your code or problem interests anyone they will reply. your attitude has
already lost you several possible repliers including me. not much more
to say.

uri
 
D

Dave Weaver

On Thu, 22 Nov 2007 15:18:00 -0800 (PST),
When I was asked to post my code, I did it.. If you don't want to
help.. pl. kindly stay away. Pl. understand that I am stuck with an
issue and that I am not fooling around here. I have clearly told what
the issue is, what I have done and I am seeking out for some help
here.

Some important things you should know:

* read the posting guidlines that are posted here regularly. They
will show you how best to post your question in order to get the
best answers. One of the suggestions here is to post a *complete*
yet *short* peice of code that demonstrates your problem, that
other people can run. Complete with a sample of input data, and
the expected output.

* asking one of the most knowledgable and helpful regulars here to
"kindly stay away" is not the best way to get quality answers.

* I missed the first post in this thread, and since then *nothing*
you wrote has explained the problem you have.

* Usenet isn't an instant-response medium. This newsgroup is read
by people all across the world, so replying to your own post
pestering people to please take a look (for the umpteenth time)
is only going to annoy people, and once again you have reduced
your chances of a helpful answer. Be patient.
 
N

nolo contendere

c> When I was asked to post my code, I did it.. If you don't want to
c> help.. pl. kindly stay away. Pl. understand that I am stuck with an
c> issue and that I am not fooling around here. I have clearly told what
c> the issue is, what I have done and I am seeking out for some help
c> here.

did you pay for your service here? since you didn't you don't have a
right to expect anything from usenet. you just post code and ask for
help and shut up about it. this is a place to discuss perl issues and if
your code or problem interests anyone they will reply. your attitude has
already lost you several possible repliers including me. not much more
to say.

What am I missing here? It appears that for some reason the number of
keys in my hash are doubling for no reason.

use strict; use warnings;
use Data::Dumper;

my %ids;

while ( <DATA> ) {
next if /^\s*$/;
chomp;
my ( $userid, $uid, $mid ) = split;
$ids{$uid} = { userid => $userid,
mid => $mid,
managerid => '' };
}

print Dumper( \%ids ), "\n";

my $num_keys = keys %ids;
print "num_keys: $num_keys\n";

my $itr = 0;
for my $key ( %ids ) {
print ++$itr, " $key\n";
# my $managerid;
# my $mid = $ids{$key}{mid};

# print "mid: $mid\n";

# find userid where uid = this $mid
# if ( exists $ids{$mid} ) {
# $managerid = lookup_userid( $mid );
# $ids{$key}{managerid} = $managerid;
# }
}

print '-' x 20, "\n";
print Dumper( \%ids ), "\n";



#=========
# subs
#=========

sub lookup_userid {
my ( $mid ) = @_;
return $ids{$mid}{userid};
}


__DATA__
jsmiths 00206251 00207609
jcarter 00207609 00220458
cgoldberg 00220458 00202003
hwatson 00202003 00201869



--------------
__OUTPUT__
bash-2.03$ ./par_chld.pl
$VAR1 = {
'00206251' => {
'mid' => '00207609',
'userid' => 'jsmiths',
'managerid' => ''
},
'00202003' => {
'mid' => '00201869',
'userid' => 'hwatson',
'managerid' => ''
},
'00207609' => {
'mid' => '00220458',
'userid' => 'jcarter',
'managerid' => ''
},
'00220458' => {
'mid' => '00202003',
'userid' => 'cgoldberg',
'managerid' => ''
}
};

num_keys: 4
1 00206251
2 HASH(0x11acd0)
3 00202003
4 HASH(0x1bf570)
5 00207609
6 HASH(0x11abec)
7 00220458
8 HASH(0x1a9ce8)
--------------------
$VAR1 = {
'00206251' => {
'mid' => '00207609',
'userid' => 'jsmiths',
'managerid' => ''
},
'00202003' => {
'mid' => '00201869',
'userid' => 'hwatson',
'managerid' => ''
},
'00207609' => {
'mid' => '00220458',
'userid' => 'jcarter',
'managerid' => ''
},
'00220458' => {
'mid' => '00202003',
'userid' => 'cgoldberg',
'managerid' => ''
}
};




When I remove my comments in my for loop, I get a data structure that
allows me to answer the ops question, but this bizarre issue comes up
with extra hash keys. Have I just not drunk enough coffee??
 
N

nolo contendere

What am I missing here? It appears that for some reason the number of
keys in my hash are doubling for no reason.

use strict; use warnings;
use Data::Dumper;

my %ids;

while ( <DATA> ) {
next if /^\s*$/;
chomp;
my ( $userid, $uid, $mid ) = split;
$ids{$uid} = { userid => $userid,
mid => $mid,
managerid => '' };

}

print Dumper( \%ids ), "\n";

my $num_keys = keys %ids;
print "num_keys: $num_keys\n";

my $itr = 0;
for my $key ( %ids ) {
print ++$itr, " $key\n";
# my $managerid;
# my $mid = $ids{$key}{mid};

# print "mid: $mid\n";

# find userid where uid = this $mid
# if ( exists $ids{$mid} ) {
# $managerid = lookup_userid( $mid );
# $ids{$key}{managerid} = $managerid;
# }

}

print '-' x 20, "\n";
print Dumper( \%ids ), "\n";

#=========
# subs
#=========

sub lookup_userid {
my ( $mid ) = @_;
return $ids{$mid}{userid};

}

__DATA__
jsmiths 00206251 00207609
jcarter 00207609 00220458
cgoldberg 00220458 00202003
hwatson 00202003 00201869

--------------
__OUTPUT__
bash-2.03$ ./par_chld.pl
$VAR1 = {
'00206251' => {
'mid' => '00207609',
'userid' => 'jsmiths',
'managerid' => ''
},
'00202003' => {
'mid' => '00201869',
'userid' => 'hwatson',
'managerid' => ''
},
'00207609' => {
'mid' => '00220458',
'userid' => 'jcarter',
'managerid' => ''
},
'00220458' => {
'mid' => '00202003',
'userid' => 'cgoldberg',
'managerid' => ''
}
};

num_keys: 4
1 00206251
2 HASH(0x11acd0)
3 00202003
4 HASH(0x1bf570)
5 00207609
6 HASH(0x11abec)
7 00220458
8 HASH(0x1a9ce8)
--------------------
$VAR1 = {
'00206251' => {
'mid' => '00207609',
'userid' => 'jsmiths',
'managerid' => ''
},
'00202003' => {
'mid' => '00201869',
'userid' => 'hwatson',
'managerid' => ''
},
'00207609' => {
'mid' => '00220458',
'userid' => 'jcarter',
'managerid' => ''
},
'00220458' => {
'mid' => '00202003',
'userid' => 'cgoldberg',
'managerid' => ''
}
};

When I remove my comments in my for loop, I get a data structure that
allows me to answer the ops question, but this bizarre issue comes up
with extra hash keys. Have I just not drunk enough coffee??

omg. I forgot 'keys' in the loop. not enough coffee.
 
N

nolo contendere

Hi all,

I am struggling with the below puzzle:

Here is the contents of a file, c:\test.txt

============================================================
user id name uid mid

jsmiths john 00206251 00207609
jcarter joseph 00207609 00220458
mstella mary 00202227 00207609
cgoldberg cindy 00220458 00202003
mshiva murthy 00224981 00207609
hwatson henry 00202003 00201869
=============================================================

jcarter is the manager of jsmiths, mstella and mshiva;
cgoldberg is the manager of jcarter;
hwatson is the manager of cgoldberg;

In the output file, I need to replace the mid with the manager id as
follows. And the topmost manager (hwatson) can remain with his id.

================================================
user id name manager id

jsmiths john jcarter
jcarter joseph cgoldberg
mstella mary jcarter
cgoldberg cindy hwatson
mshiva murthy jcarter
hwatson henry hwatson
=================================================



use strict; use warnings;
use Data::Dumper;

my %ids;

while ( <DATA> ) {
next if /^\s*$/;
chomp;
my ( $userid, $uid, $mid ) = split;
$ids{$uid} = { userid => $userid,
mid => $mid,
managerid => '' };
}

my $itr = 0;
for my $key ( keys %ids ) {
my $managerid;
my $mid = $ids{$key}{mid};

# find userid where uid = this $mid
if ( exists $ids{$mid} ) {
$managerid = lookup_userid( $mid );
$ids{$key}{managerid} = $managerid;
}
}

for my $uid ( keys %ids ) {
unless ( $ids{$uid}{managerid} ) { $ids{$uid}{managerid} =
$ids{$uid}{userid}; };
print "$ids{$uid}{userid}\t$ids{$uid}{managerid}\n";
}


#=========
# subs
#=========

sub lookup_userid {
my ( $mid ) = @_;
return $ids{$mid}{userid};
}


__DATA__
jsmiths 00206251 00207609
jcarter 00207609 00220458
cgoldberg 00220458 00202003
hwatson 00202003 00201869



========
__OUTPUT__
jsmiths jcarter
hwatson hwatson
jcarter cgoldberg
cgoldberg hwatson
 
B

Brian McCauley

use strict; use warnings;
use Data::Dumper;

my %ids;

Good start.
while ( <DATA> ) {
next if /^\s*$/;
chomp;
my ( $userid, $uid, $mid ) = split;
$ids{$uid} = { userid => $userid,
mid => $mid,
managerid => '' };

}

I tend to follow the rule "always use the most natural representation
of things unless there is a reason to do otherwise". (It's one of my
top-five rules of programming).

In this case the "natural representation" of a hash not (yet) having a
managerid entry would be for it not to have a managerid entry.
my $itr = 0;

You never use $itr
for my $key ( keys %ids ) {

Since you never use $key except to look up $ids{$key} it would be more
efficient to loop over the values directly.
my $managerid;

You are declaring this in the wrong scope.
my $mid = $ids{$key}{mid};

# find userid where uid = this $mid
if ( exists $ids{$mid} ) {

There's nothing wrong with using exists() here but it is redundant
since we know that %ids will contain no false values.
$managerid = lookup_userid( $mid );

This is where you should have declared $managerid (but since you only
use it once it's maybe not worth it at all).
$ids{$key}{managerid} = $managerid;
}

}

for my $uid ( keys %ids ) {
unless ( $ids{$uid}{managerid} ) { $ids{$uid}{managerid} =
$ids{$uid}{userid}; };

More simply

$ids{$uid}{managerid} ||= $ids{$uid}{userid};

However it would probably make sense to distinguish in some way
entries with no mid from those with an invalid mid.
print "$ids{$uid}{userid}\t$ids{$uid}{managerid}\n";

}

#=========
# subs
#=========

sub lookup_userid {
my ( $mid ) = @_;
return $ids{$mid}{userid};

}

This function is probably too small to be worth it. Particularly given
the global variable.

The reasoning goes like this

Accessors - good

Global variables - bad

More complexity - bad

Nett gain - negative
 

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,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top