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

hello, not sure if this is a simple question or not. i have a array with duplicate values. so:
my @array = ("1", "3", "3","3", "5", "5", "5", "5");
now what i need to return is an array that will store the number of times each unique value appears inside the @array. so my new array would need to look like this
my @new_array = ("1", "3", "4");
i really dont know enough at this moment to write a routine that will create this array which stores the amount each unique values. thanks for reading this lads.

John

Replies are listed 'Best First'.
Re: extract number of times a value appears in an array
by GrandFather (Saint) on Aug 17, 2006 at 23:21 UTC
Re: extract number of times a value appears in an array
by liverpole (Monsignor) on Aug 17, 2006 at 23:24 UTC
    If this is a homework assignment, you really should read this node first.

    And if it's not a homework assignment, it would be a good idea to provide some code first, to show how you've attempted to go about it solving it.  (But why are you trying to do this in Perl in the first place, if you have not encountered hashes before??)

    In any event, try reading up on hashes first.  A good start might be perlintro.


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
Re: extract number of times a value appears in an array
by davido (Cardinal) on Aug 18, 2006 at 02:40 UTC

    Here's one way to do it. This way doesn't preserve original order, but it does sort the frequency list based on the numerical order of the input list, which seems to be how your example data was sorted. Given your example input and output, my script produces the output list in the same order your example demonstrated.

    I would think it would be more useful to maintain a key/value relationship so that instead of only ending up with a list of frequencies, you would end up with a set of item/frequency pairs. My solution could be easily adapted to do that instead, should your specification change to include that requirment.

    use strict; use warnings; my @items = ( 1, 3, 3, 3, 5, 5, 5, 5 ); my @frequency = @{ frequency( \@items ) }; print "@frequency\n"; sub frequency { my $items_ref = shift; my %counter; $counter{$_}++ for @{$items_ref}; return [ map { $counter{$_} } sort { $a <=> $b } keys %counter ]; }

    Dave

Re: extract number of times a value appears in an array
by imp (Priest) on Aug 17, 2006 at 23:46 UTC
    Based on your expected result set it seems the order in which the entries appear is significant. Are the following two lists equivalent as input data?
    my @array = (1,3,3,3,5,5,5,5); my @array = (1,3,3,5,5,5,5,3);
Re: extract number of times a value appears in an array
by jwkrahn (Abbot) on Aug 18, 2006 at 02:55 UTC
    $ perl -Mwarnings -Mstrict -le' my @array = qw( 1 3 3 3 5 5 5 5 ); my %count; my @new_array = map { ++$count{ $array[ $_ ] }; no warnings q/uninitialized/; $array[ $_ ] eq $array[ $_ + 1 ] ? () : $count{ $array[ $_ ] } } 0 .. $#array; print "@new_array"; ' 1 3 4
Re: extract number of times a value appears in an array
by Anonymous Monk on Aug 18, 2006 at 00:42 UTC
    This is not homework lol.

    I wish it was though, wouldn't be as stressful.

    My coding

    #made this events_array up... but the concept remains It will always be in a particular order, least to greatest in this cas +e. @events_aray = ("1","3","3","4","5","5"); my %days; my @appears; my @date_count; my $c = 0; foreach my $v (@events_aray) { #this foreach will split the values of the array I have populated #it will then produce a hash with keys as a date. #another array will be generated containing each dates of the event. + my ($date, $subject, $text) = split(/,/, $events_array); $days{$date} .= "<b>$subject($symbolx)<b><br><br>$text<br><br>"; $date_count[$c] = "$date"; #this stores the date of the event, thi +s will be the array I need to figure out how many times each date app +ears $c++; } #some subroutine to figure out how to retrieve the amount. #The array + that I said I needed to generate will be @appears. #this is where I need a little help on. I will continue #looking thou +gh and if resolved I will post back asap. $c = 0; foreach my $u (keys %days) { print "date appeared $appears[$c] times"; print "<br><br>$days{$u}"; $c++; }
    Thats what I have so far....

    thanks, John

      The count part of the problem I'd solve thus:

      use strict; use warnings; my @events_aray = (1, 3, 3, 4, 5, 5); my %days; ++$days{$_} for @events_aray; print "date $_ appeared $days{$_} times\n" for sort {$a <=> $b} keys %days;

      Prints:

      date 1 appeared 1 times date 3 appeared 2 times date 4 appeared 1 times date 5 appeared 2 times

      You may need a different sort if your values are not numbers.


      DWIM is Perl's answer to Gödel
Re: extract number of times a value appears in an array
by Mandrake (Chaplain) on Aug 18, 2006 at 06:32 UTC
    Try
    #!/usr/bin/perl -w use strict; my @items = ( 1, 3, 3, 1,3, 5, 5, 5, 5,3 ); my %count; $count{$_}++ for (sort @items); print "day ".$_." appeared ".$count{$_}." times\n" for (keys %count);
Re: extract number of times a value appears in an array
by leocharre (Priest) on Aug 18, 2006 at 14:26 UTC
    #!/usr/bin/perl -w use strict; use Data::Dumper; my $count={}; my @a =qw(1 2 3 4 5 5 5 5); map { $count->{$_}++ } @a; print Dumper($count);

    grep and map in perl

      Whilst recent versions of Perl do away with the memory problems of using map in a void context, it still seems strange to me to use map purely for its side effects. Particularly when for usually works just as well.

      $count->{$_}++ for @a;
      --
      <http://dave.org.uk>

      "The first rule of Perl club is you do not talk about Perl club."
      -- Chip Salzenberg