Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Array question

by udinakar (Novice)
on Sep 05, 2007 at 10:25 UTC ( [id://637112]=perlquestion: print w/replies, xml ) Need Help??

udinakar has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I have a array like this.
[[01 Jul 2007,221.6.19.196,9,19], [01 Jul 2007,221.6.19.197,1,3], [01 Jul 2007,221.6.19.196,12,12], [01 Jul 2007,221.6.19.197,2 ,2], [02 Jul 2007,202.119.104.22,1,1], [02 Jul 2007,221.6.19.196,20,45], [03 Jul 2007,202.119.104.12,1,11], [03 Jul 2007,202.119.110.236,1,2], [03 Jul 2007,210.29.132.9,1,2], [03 Jul 2007,210.29.141.188,1,2], [03 Jul 2007,221.6.19.195,3,7], [03 Jul 2007,221.6.19.196,4,7], [03 Jul 2007,222.192.2.213,1,0], [03 Jul 2007,202.119.108.42,3,3]]
I need the output as
[[01 Jul 2007,221.6.19.196,21,31], [01 Jul 2007,221.6.19.197,3,5], [02 Jul 2007,202.119.104.22,1,1], [02 Jul 2007,221.6.19.196,20,45], [03 Jul 2007,202.119.104.12,1,11], [03 Jul 2007,202.119.110.236,1,2], [03 Jul 2007,210.29.132.9,1,2], [03 Jul 2007,210.29.141.188,1,2], [03 Jul 2007,221.6.19.195,3,7], [03 Jul 2007,221.6.19.196,4,7], [03 Jul 2007,222.192.2.213,1,0], [03 Jul 2007,202.119.108.42,3,3]]
repeated ip count should be clubed for each day. Please help Thanks, Dinakar

Replies are listed 'Best First'.
Re: Array question
by moritz (Cardinal) on Sep 05, 2007 at 10:47 UTC
    Store the data in a hash, with Date+IP as the key and the repetition count as the value. When you enter an array item into the hash, you just add the count in the last column to the current value.
      Great suggestion,
      <shameless-plug>Have a look at The Uniqueness of hashes. to see some examples of just this sort of thing.</shameless-plug>

      -InjunJoel
      "I do not feel obliged to believe that the same God who endowed us with sense, reason and intellect has intended us to forego their use." -Galileo
Re: Array question
by andreas1234567 (Vicar) on Sep 05, 2007 at 10:48 UTC
    Something like:
    use strict; use warnings; my %hash = (); for (<DATA>) { chomp; my ($day, $ip, $i, $j) = split(q{,}, $_); $hash{$day}{$ip}{i} += $i; $hash{$day}{$ip}{j} += $j; } foreach my $day (sort keys %hash) { foreach my $ip (sort keys %{$hash{$day}}) { print qq{$day,$ip,} . $hash{$day}{$ip}{i} . q{,}. $hash{$day}{$ip}{j}; } } __DATA__ 01 Jul 2007,221.6.19.196,9,19 01 Jul 2007,221.6.19.197,1,3 01 Jul 2007,221.6.19.196,12,12 01 Jul 2007,221.6.19.197,2 ,2 02 Jul 2007,202.119.104.22,1,1 02 Jul 2007,221.6.19.196,20,45 03 Jul 2007,202.119.104.12,1,11 03 Jul 2007,202.119.110.236,1,2 03 Jul 2007,210.29.132.9,1,2 03 Jul 2007,210.29.141.188,1,2 03 Jul 2007,221.6.19.195,3,7 03 Jul 2007,221.6.19.196,4,7 03 Jul 2007,222.192.2.213,1,0 03 Jul 2007,202.119.108.42,3,3
    $ perl -l 637112.pl 01 Jul 2007,221.6.19.196,21,31 01 Jul 2007,221.6.19.197,3,5 02 Jul 2007,202.119.104.22,1,1 02 Jul 2007,221.6.19.196,20,45 03 Jul 2007,202.119.104.12,1,11 03 Jul 2007,202.119.108.42,3,3 03 Jul 2007,202.119.110.236,1,2 03 Jul 2007,210.29.132.9,1,2 03 Jul 2007,210.29.141.188,1,2 03 Jul 2007,221.6.19.195,3,7 03 Jul 2007,221.6.19.196,4,7 03 Jul 2007,222.192.2.213,1,0
    Update: Renamed variables from $a, $b to $i, $j as adviced by GrandFather.
    --
    Andreas

      Please avoid using $a and $b as general purpose variables. They are "magic" variables used by sort.


      DWIM is Perl's answer to Gödel
        Any good pointers to read about this magic variables.Really wanna know grainy details about them

        The world is so big for any individual to conquer

Re: Array question
by GrandFather (Saint) on Sep 05, 2007 at 10:49 UTC

    We like to see that you have made a little effort, partly so that we know you have actually thought about the problem and are not just hoping someone will save you having to do any work, and partly to gage your level of understanding of Perl and programming.

    To get you started you should take a look at perlretut and perlre to gain a little understanding of pattern matching using regular expressions.

    You will also find it helpful to go back to basics by looking at hashes and their application for managing data accessed by unique keys (see perldata).


    DWIM is Perl's answer to Gödel
      Actually this is a table reterived from the database and i tried this
      my @new_duplicateip_results; foreach my $first (@$select_result) { foreach my $second (@$select_result) { if ((@$first->[0] eq @$second->[0]) && (@$first->[1] eq @$seco +nd->[1]) && (@$first->[$#{$first}] eq $self->product_id) && (@$second +->[$#{$second}] eq "WS-".$self->product_id)) { my $ip_string = "@$first->[0],@$first->[1],"; foreach (2..$#{$first}) { $ip_string .= @$first->[$_]+@$second->[$_].","; } my @split_array = split(/,/,$ip_string) ; push @new_duplicateip_results,\@split_array; } } } foreach (@new_duplicateip_results) { print STDERR join "#",@$_; print STDERR "\n"; }
      However i need the values that are not matching the creiria. If i include else then multiple rows are fetched. Thanks, Dinakar

        I apologize for leaping to the worst interpretation of your post! I hope the code below helps. It will muck up the date ordering, but I've run out of time tonight to clean that up.

        use strict; use warnings; use Data::Dump::Streamer; my @data = ( ['01 Jul 2007','221.6.19.196',9,19], ['01 Jul 2007','221.6.19.197',1,3], ['01 Jul 2007','221.6.19.196',12,12], ['01 Jul 2007','221.6.19.197',2,2], ['02 Jul 2007','202.119.104.22',1,1], ['02 Jul 2007','221.6.19.196',20,45], ['03 Jul 2007','202.119.104.12',1,11], ['03 Jul 2007','202.119.110.236',1,2], ['03 Jul 2007','210.29.132.9',1,2], ['03 Jul 2007','210.29.141.188',1,2], ['03 Jul 2007','221.6.19.195',3,7], ['03 Jul 2007','221.6.19.196',4,7], ['03 Jul 2007','222.192.2.213',1,0], ['03 Jul 2007','202.119.108.42',3,3], ); my %sums; $sums{$_->[0]}{a} += $_->[1], $sums{$_->[0]}{b} += $_->[2] for map {["$_->[0],$_->[1]", @{$_}[2,3]]} @data; my @result = map {[@{$_}[1, 2, 3, 4]]} sort {$a->[0] cmp $b->[0]} map {[$_, split (',', $_), @{$sums{$_}}{'a', 'b'}]} keys %sums; Dump (\@result);

        Prints:

        $ARRAY1 = [ [ '01 Jul 2007', '221.6.19.196', 21, 31 ], [ '01 Jul 2007', '221.6.19.197', 3, 5 ], [ '02 Jul 2007', '202.119.104.22', ( 1 ) x 2 ], [ '02 Jul 2007', '221.6.19.196', 20, 45 ], [ '03 Jul 2007', '202.119.104.12', 1, 11 ], [ '03 Jul 2007', '202.119.108.42', ( 3 ) x 2 ], [ '03 Jul 2007', '202.119.110.236', 1, 2 ], [ '03 Jul 2007', '210.29.132.9', 1, 2 ], [ '03 Jul 2007', '210.29.141.188', 1, 2 ], [ '03 Jul 2007', '221.6.19.195', 3, 7 ], [ '03 Jul 2007', '221.6.19.196', 4, 7 ], [ '03 Jul 2007', '222.192.2.213', 1, 0 ] ];

        DWIM is Perl's answer to Gödel

        If this is a table why don't you let the database do the work?

        SELECT date, ip, sum(a), sum(b) FROM table GROUP BY date, ip

        ___________
        Eric Hodges
Re: Array question
by narainhere (Monk) on Sep 05, 2007 at 10:57 UTC
    Build a hash with date and ip adress as key,and keep the values in an array After reading the first two entries the hash would look like this,
    %myhash{ "01 Jul 2007,221.6.19.196"=>[9,19], "01 Jul 2007,221.6.19.197"=>[1,3] }
    Now the third ipaddress and date is same as first one,so add up the new values with the already existing values.Once you have parsed the entire list,can get you o/p by printing the key's and value's of the array.Please throw in some sentences on you next post's, your post looks like a command to a computer ;)

    The world is so big for any individual to conquer

      Sorry for being redundant.Didn't thought so many replies would have come before I post.
Re: Array question
by Cristoforo (Curate) on Sep 05, 2007 at 23:43 UTC
    I thought I'd post this solution because it has the two different sorts needed.

    Chris

    #!/usr/bin/perl use strict; use warnings; use Socket; # program uses the inet_aton and inet_ntoa functions my %month; @month{ qw/ Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/} = '01'.. +'12'; my %data; while (<DATA>) { my ($date, $ip, $count1, $count2) = split /,/; $data{$date}{ inet_aton($ip) }{count1} += $count1; $data{$date}{ inet_aton($ip) }{count2} += $count2; } for my $date (sort by_date keys %data) { for my $ip (sort keys %{ $data{$date} }) { my $c1 = $data{$date}{$ip}{count1}; my $c2 = $data{$date}{$ip}{count2}; print join(",", $date, inet_ntoa($ip), $c1, $c2), "\n"; } } sub by_date { my ($d_a, $m_a, $y_a) = split ' ', $a; my ($d_b, $m_b, $y_b) = split ' ', $b; my $A = "$y_a$month{$m_a}$d_a"; my $B = "$y_b$month{$m_b}$d_b"; $A cmp $B; } __DATA__ 01 Jul 2007,221.6.19.196,9,19 01 Jul 2007,221.6.19.197,1,3 01 Jul 2007,221.6.19.196,12,12 01 Jul 2007,221.6.19.197,2 ,2 02 Jul 2007,202.119.104.22,1,1 02 Jul 2007,221.6.19.196,20,45 03 Jul 2007,202.119.104.12,1,11 03 Jul 2007,202.119.110.236,1,2 03 Jul 2007,210.29.132.9,1,2 03 Jul 2007,210.29.141.188,1,2 03 Jul 2007,221.6.19.195,3,7 03 Jul 2007,221.6.19.196,4,7 03 Jul 2007,222.192.2.213,1,0 03 Jul 2007,202.119.108.42,3,3 03 Aug 2007,221.6.110.9,1,2 03 Aug 2007,221.6.110.9,10,10 ***prints C:\perlp>perl t7.pl 01 Jul 2007,221.6.19.196,21,31 01 Jul 2007,221.6.19.197,3,5 02 Jul 2007,202.119.104.22,1,1 02 Jul 2007,221.6.19.196,20,45 03 Jul 2007,202.119.104.12,1,11 03 Jul 2007,202.119.108.42,3,3 03 Jul 2007,202.119.110.236,1,2 03 Jul 2007,210.29.132.9,1,2 03 Jul 2007,210.29.141.188,1,2 03 Jul 2007,221.6.19.195,3,7 03 Jul 2007,221.6.19.196,4,7 03 Jul 2007,222.192.2.213,1,0 03 Aug 2007,221.6.110.9,11,12
      Thanks to one and all. My apology for delayed response. I have taken the logic of GrandFather and tweaked it to my requirment it WORKED. I was caught up with that work. Special thanks to GrandFather. I cannot do it from the database as there is a constraint in the logic built. Thanks, Dinakar

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://637112]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (2)
As of 2024-04-26 05:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found