Help on massaging some data

R

Rider

Hi experts,

I need a little help on the below data massage.

In the output, I need to get only the users with the respective
multiple groups. If a user belongs to only one group, we need to
ignore that entry.

I am struggling with code here. I am trying to do it with hashes
instead of the arrays.

Can some one help me here?



The output (two columns should be seperated by two tabs) of the below
__DATA__ should be as follows (pl. note that the two columns of data
are seperated by a single tab in __DATA__ content):

1. burt 1). google_abc
2). google_abc_def
2. mike 1). amazon_abc
2). yahoo_xyz
3). google_abc
3. zack 1). yahoo_abc
2). ebay_abc
3). google_abc
4). amazon_abc


__DATA__
alissa yahoo_xyz
burt google_abc
burt google_abc_def
mike amazon_abc
mike yahoo_xyz
mike google_abc
will yahoo_abc
zack yahoo_abc
zack ebay_abc
zack google_abc
zack amazon_abc
 
S

sln

In the output, I need to get only the users with the respective
multiple groups. If a user belongs to only one group, we need to
ignore that entry.
The output (two columns should be seperated by two tabs) of the below
__DATA__ should be as follows (pl. note that the two columns of data
are seperated by a single tab in __DATA__ content):

1. burt 1). google_abc
2). google_abc_def
2. mike 1). amazon_abc
2). yahoo_xyz
3). google_abc
3. zack 1). yahoo_abc
2). ebay_abc
3). google_abc
4). amazon_abc
Its not so hard, why are you struggling?
I can get hard depending on how you deviate
from this simplistic example.

-sln
-------------
use strict;
use warnings;

my %users;
while (<DATA>) {
if (/\s*(\w+)\s+(\w+)\s*/) {
$users{$1}->{$2}++;
}
}
while (my ($person, $groups) = each %users) {
delete $users{$person}, next if (keys %$groups == 1);
print "$person -\n";
print "\t$_\n" for (sort keys %$groups);
}
__DATA__
mike amazon_abc
mike yahoo_xyz
mike google_abc
alissa yahoo_xyz
will yahoo_abc
zack yahoo_abc
zack ebay_abc
zack google_abc
zack amazon_abc
burt google_abc
burt google_abc_def
 
J

Jürgen Exner

Rider said:
In the output, I need to get only the users with the respective
multiple groups. If a user belongs to only one group, we need to
ignore that entry.


Use a HoA (hash of array), where the user's name is the hash key and
each every group he belongs to is push()ed onto the array.

Then, after reading all the input data, simply print each hash entry
while skipping those entries, where there is only one element in the
array.

jue
 
J

John W. Krahn

Rider said:
Hi experts,

I need a little help on the below data massage.

In the output, I need to get only the users with the respective
multiple groups. If a user belongs to only one group, we need to
ignore that entry.

I am struggling with code here. I am trying to do it with hashes
instead of the arrays.

Can some one help me here?



The output (two columns should be seperated by two tabs) of the below
__DATA__ should be as follows (pl. note that the two columns of data
are seperated by a single tab in __DATA__ content):

1. burt 1). google_abc
2). google_abc_def
2. mike 1). amazon_abc
2). yahoo_xyz
3). google_abc
3. zack 1). yahoo_abc
2). ebay_abc
3). google_abc
4). amazon_abc


__DATA__
alissa yahoo_xyz
burt google_abc
burt google_abc_def
mike amazon_abc
mike yahoo_xyz
mike google_abc
will yahoo_abc
zack yahoo_abc
zack ebay_abc
zack google_abc
zack amazon_abc

$ perl -e'
my $mydata = <<MYDATA;
alissa yahoo_xyz
burt google_abc
burt google_abc_def
mike amazon_abc
mike yahoo_xyz
mike google_abc
will yahoo_abc
zack yahoo_abc
zack ebay_abc
zack google_abc
zack amazon_abc
MYDATA

open my $FH, "<", \$mydata or die "open: $!";

my ( @order, %data );
while ( <$FH> ) {
my ( $name, $addr ) = split or next;
push @order, $name unless exists $data{ $name };
push @{ $data{ $name } }, $addr;
}

for my $i ( 0 .. $#order ) {
next if @{ $data{ $order[ $i ] } } == 1;
print $i + 1, ". $order[ $i ]";
for my $j ( 0 .. $#{ $data{ $order[ $i ] } } ) {
print "\t", $j + 1, "). $data{ $order[ $i ] }[ $j ]\n";
}
}
'
2. burt 1). google_abc
2). google_abc_def
3. mike 1). amazon_abc
2). yahoo_xyz
3). google_abc
5. zack 1). yahoo_abc
2). ebay_abc
3). google_abc
4). amazon_abc




John
 
C

ccc31807

In the output, I need to get only the users with the respective
multiple groups. If a user belongs to only one group, we need to
ignore that entry.

Create two hashes, one to count to number of groups (%count) and the
other to hold a reference to an array with the groups (%users). Then,
print the %users hash if the %count hash is greater than one.


CODE:
use strict;
use warnings;

my (%users, %count);

while (<DATA>)
{
next unless /\w/;
chomp;
my ($user, $group) = split;
push @{$users{$user}}, $group;
$count{$user}++;
}

foreach my $user (sort keys %users)
{
next unless $count{$user} > 1;
foreach my $ele (@{$users{$user}})
{
print "$user => $ele ";
}
print "\n"
}

exit(0);

__DATA__
alissa yahoo_xyz
burt google_abc
burt google_abc_def
mike amazon_abc
mike yahoo_xyz
mike google_abc
will yahoo_abc
zack yahoo_abc
zack ebay_abc
zack google_abc
zack amazon_abc

OUTPUT:

$ perl user_groups.plx
burt => google_abc burt => google_abc_def
mike => amazon_abc mike => yahoo_xyz mike => google_abc
zack => yahoo_abc zack => ebay_abc zack => google_abc zack =>
amazon_abc
 
J

Justin C

Hi experts,

You aren't addressing me, obviously.

I need a little help on the below data massage.

I am struggling with code here. I am trying to do it with hashes
instead of the arrays.

Can some one help me here?

The output (two columns should be seperated by two tabs) of the below
__DATA__ should be as follows (pl. note that the two columns of data
are seperated by a single tab in __DATA__ content):

1. burt 1). google_abc
2). google_abc_def
2. mike 1). amazon_abc
2). yahoo_xyz
3). google_abc
3. zack 1). yahoo_abc
2). ebay_abc
3). google_abc
4). amazon_abc

__DATA__
alissa yahoo_xyz
burt google_abc
burt google_abc_def
mike amazon_abc
mike yahoo_xyz
mike google_abc
will yahoo_abc
zack yahoo_abc
zack ebay_abc
zack google_abc
zack amazon_abc

I'd use a hash of arrays.

push @{$names{$name}}, $group;
..
..
if (@{$names{$name}} > 1 ) {
 

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,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top