Help on massaging some data

Discussion in 'Perl Misc' started by Rider, Oct 7, 2009.

  1. Rider

    Rider Guest

    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
     
    Rider, Oct 7, 2009
    #1
    1. Advertising

  2. Rider

    Guest

    On Wed, 7 Oct 2009 15:39:02 -0700 (PDT), Rider <> wrote:

    >
    >

    <snip>
    >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.
    >

    <snip>
    >
    >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
     
    , Oct 8, 2009
    #2
    1. Advertising

  3. Rider <> wrote:
    >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ürgen Exner, Oct 8, 2009
    #3
  4. Rider wrote:
    >
    > 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
    --
    The programmer is fighting against the two most
    destructive forces in the universe: entropy and
    human stupidity. -- Damian Conway
     
    John W. Krahn, Oct 8, 2009
    #4
  5. Rider

    ccc31807 Guest

    On Oct 7, 6:39 pm, Rider <> wrote:
    > 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
     
    ccc31807, Oct 8, 2009
    #5
  6. Rider

    Justin C Guest

    On 2009-10-07, Rider <> wrote:
    >
    > 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 ) {
     
    Justin C, Oct 8, 2009
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Guest
    Replies:
    0
    Views:
    707
    Guest
    Feb 25, 2004
  2. Domino
    Replies:
    5
    Views:
    415
    dorayme
    Nov 5, 2006
  3. Taylor Strait

    Need help massaging some strings

    Taylor Strait, Dec 28, 2006, in forum: Ruby
    Replies:
    4
    Views:
    127
    Paulo Köch
    Dec 28, 2006
  4. LeTubs
    Replies:
    6
    Views:
    136
    Tad McClellan
    Jan 25, 2004
  5. Replies:
    3
    Views:
    241
Loading...

Share This Page