count each unique record



IBM's Command List programming language & Restructured Extended Executor

count each unique record

Postby xboss » Sun Dec 23, 2012 11:48 pm

Hello all,
Last time I posted a topic "Count number of volume and cylinders of each DASD" which according to forum veteran was ambiguous topic ( I accept it). So I am starting new topic which I believe is straight forward (hope so :D)
My requirement is to count each unique record and sum its associated value for example,
AAAA 20
BBBB 10
BBBB 4
BBBB 1600
BBBB 33
CCCC 5
CCCC 9
CCCC 12
DDDD 13
DDDD 14

If above is my input, my output should be

RECORD COUNT SUM
AAAA 1 20
BBBB 4 1647
CCCC 3 26
DDDD 2 27

I know this can be done easily with SORT (though I don't know the exact syntax) but I am finding a way to do it with REXX. So far, I am only able to count the unique number of records (which is 4 in this case but not each unique record)

  count = 0                                 
  DO j = 1 to i-1                           
     k = j + 1                             
     if (serial.j == serial.k) then iterate
     else count = count + 1                 
  END                                       
  say count                                 


I started with Akatsukami suggestion by sorting the records first, but no luck after than. Sorry for making this long, but any help would be really appreciated. Help this poor beginner who wants to learn. :(
xboss
 
Posts: 79
Joined: Mon Nov 29, 2010 10:55 am
Has thanked: 0 time
Been thanked: 0 time

Re: count each unique record

 

Re: count each unique record

Postby enrico-sorichetti » Mon Dec 24, 2012 1:13 am

You were already given a full working solution to achieve that result here
clist-rexx/topic8595-10.html

no need to sort anything ( if the number of <major> keys is reasonable )
You will only have to parse differently the inputs
and add one additional stem variable to hold the counts
cheers
enrico
When I tell somebody to RTFM or STFW I usually have the page open in another tab/window of my browser,
so that I am sure that the information requested can be reached with a very small effort
enrico-sorichetti
Global moderator
 
Posts: 2644
Joined: Fri Apr 18, 2008 11:25 pm
Has thanked: 0 time
Been thanked: 130 times

Re: count each unique record

Postby enrico-sorichetti » Mon Dec 24, 2012 1:37 am

but since I am in a good mood here is a snippet which does it

the code
#! /usr/bin/rexx

/* k refers to the key */
/* c refers to the count */
/* s refers to the sum */

lk = ""
lc = ""
ls = ""

Address HOSTEMU "EXECIO * DISKR <your input file/YOUR INPUT DDNAME>  (stem REC. FINIS"

do  i = 1 to rec.0

    k = strip(word(rec.i,1))
    z = translate(k,"__","-*")
    s = strip(word(rec.i,2))

    if  symbol( "sum_key."z ) = "LIT" then do

        interpret "sum_key."z" = k"
        interpret "sum_cnt."z" = 1"
        interpret "sum_sum."z" = s"

        lk = lk "sum_key."z
        lc = lc "sum_cnt."z
        ls = ls "sum_sum."z

    end
    else do
        interpret "sum_cnt."z" = sum_cnt."z" + 1"
        interpret "sum_sum."z" = sum_sum."z" + s"
    end

end

say left("key",8) right("count",8) right("sum",8)
say ""
do  i = 1 to words(lk)
    say left(value(word(lk,i)),8) right(value(word(lc,i)),8) right(value(word(ls,i)),8)
end

exit

::requires "hostemu" LIBRARY


the data
aaaa 10
bbbb 20
cccc 30
dddd 40
aaaa 100
bbbb 200
cccc 300
dddd 400
aaaa 1000
bbbb 2000
cccc 3000
dddd 4000
aaaa 10000
bbbb 20000
cccc 30000
dddd 40000
aaaa 100000
bbbb 200000
cccc 300000
dddd 400000
aaaa 1000000
bbbb 2000000
cccc 3000000
dddd 4000000
aaaa 1
bbbb 2
cccc 3
dddd 4


the result
key         count      sum

aaaa            7  1111111
bbbb            7  2222222
cccc            7  3333333
dddd            7  4444444



tested with object rexx on my MAC
the same logic will work for TSO ( instead of a PC file name use a ddname )
cheers
enrico
When I tell somebody to RTFM or STFW I usually have the page open in another tab/window of my browser,
so that I am sure that the information requested can be reached with a very small effort
enrico-sorichetti
Global moderator
 
Posts: 2644
Joined: Fri Apr 18, 2008 11:25 pm
Has thanked: 0 time
Been thanked: 130 times

Re: count each unique record

Postby enrico-sorichetti » Mon Dec 24, 2012 2:20 am

since it is Christmas time
here a better snippet that sorts also on ascending key

#! /usr/bin/rexx

/* k refers to the key */
/* c refers to the count */
/* s refers to the sum */

lk = ""
lc = ""
ls = ""

Address HOSTEMU "EXECIO * DISKR <...> (stem REC. FINIS"

do  i = 1 to rec.0

    k = strip(word(rec.i,1))
    z = translate(k,"__","-*")
    s = strip(word(rec.i,2))

    if  symbol( "key."z ) = "LIT" then do

        interpret "key."z" = k"
        interpret "cnt."z" = 1"
        interpret "sum."z" = s"

        lk = lk "key."z
        lc = lc "cnt."z
        ls = ls "sum."z

    end
    else do
        interpret "cnt."z" = cnt."z" + 1"
        interpret "sum."z" = sum."z" + s"
    end

end

/*  sort the keys */
lk = __sort(lk)

say left("key",8) right("count",8) right("sum",8)
say ""
do  i = 1 to words(lk)
    z = word(lk,i)
    parse var z . "." k
    say left(value(word(lk,i)),8) right(value("cnt."k),8) right(value("sum."k),8)
end

exit

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
::routine __sort public

    parse arg u
    n = words(u)
    a.0 = n
    do  i = 1 to n
        parse var u a.i u
    end

    h = a.0
    do  while h > 1;
        h = h % 2;
        do  i = 1 for a.0 - h
            j = i; k = h + i;
            do  while a.k < a.j
                t = a.j; a.j = a.k; a.k = t;
                if  h >= j then ,
                    leave;
                j = j - h; k = k - h;
            end
        end
    end

    s = ""; l = ""
    do  i = 1 to n
        c = a.i
        if  c \= l then ,
            s = s c
        l = c
    end

    return space(s)

::requires "hostemu" LIBRARY


the data
dddd 4000000
dddd 400000
dddd 40000
dddd 4000
dddd 400
dddd 40
dddd 4
cccc 3000000
cccc 300000
cccc 30000
cccc 3000
cccc 300
cccc 30
cccc 3
bbbb 2000000
bbbb 200000
bbbb 20000
bbbb 2000
bbbb 200
bbbb 20
bbbb 2
aaaa 1000000
aaaa 100000
aaaa 10000
aaaa 1000
aaaa 100
aaaa 10
aaaa 1


the result
key         count      sum

aaaa            7  1111111
bbbb            7  2222222
cccc            7  3333333
dddd            7  4444444
cheers
enrico
When I tell somebody to RTFM or STFW I usually have the page open in another tab/window of my browser,
so that I am sure that the information requested can be reached with a very small effort
enrico-sorichetti
Global moderator
 
Posts: 2644
Joined: Fri Apr 18, 2008 11:25 pm
Has thanked: 0 time
Been thanked: 130 times

Re: count each unique record

Postby enrico-sorichetti » Mon Dec 24, 2012 2:34 am

looks like You have more problems with the logic, rather than with the code

how would You approach the problem in, for example, COBOL ?
cheers
enrico
When I tell somebody to RTFM or STFW I usually have the page open in another tab/window of my browser,
so that I am sure that the information requested can be reached with a very small effort
enrico-sorichetti
Global moderator
 
Posts: 2644
Joined: Fri Apr 18, 2008 11:25 pm
Has thanked: 0 time
Been thanked: 130 times

Re: count each unique record

Postby xboss » Mon Dec 24, 2012 5:23 pm

Enrico, I have to learn both logic and syntax. Long way to go :(
Thank you for the solution. It took me a while to demystify it. Appreciate it. Merry X-mas.
xboss
 
Posts: 79
Joined: Mon Nov 29, 2010 10:55 am
Has thanked: 0 time
Been thanked: 0 time

Re: count each unique record

Postby enrico-sorichetti » Mon Dec 24, 2012 7:58 pm

Enrico, I have to learn both logic


the logic is the same as finding duplicates in an ordered file

...
read the first record...
... initialize the key ( save the current key )
... initialize the count
... initialize the sum

iterate on all the rest
... if the current key is grater than the saved key
... ... print the values for the saved key
... ... REinitialize the key ( save the current key )
... ... REinitialize the count
... ... REinitialize the sum
... else if the current key is equal to the saved key
... ... sum 1 to the count
... ... sum the current value to the sum
... else ... record out of sequence
... ... tell so and terminate, or tell so and discard the record
... end if
end of iteration
print the values for the saved key
exit

and here is the snippet that does it

#! /usr/bin/rexx

/* k refers to the key */
/* c refers to the count */
/* s refers to the sum */

Address HOSTEMU "EXECIO * DISKR <file name/DDNAME> (stem REC. FINIS"

say left("key",8) right("count",8) right("sum",8)

k = strip(word(rec.1,1))
c = 1
s = strip(word(rec.1,2))

do  i = 2 to rec.0

    select
        when ( strip(word(rec.i,1))  > k ) then do
            say left(k,8) right(c,8) right(s,8)
            k = strip(word(rec.i,1))
            c = 1
            s = strip(word(rec.i,2))
        end

        when ( strip(word(rec.i,1)) = k ) then do
            c = c + 1
            s = s + strip(word(rec.i,2))
        end

        otherwise do
            say "discarding " strip(word(rec.i,1))
        end

    end

end

say left(k,8) right(c,8) right(s,8)

exit

::requires "hostemu" LIBRARY


written for ooRexx, but can be ported easily to TSO Rexx
cheers
enrico
When I tell somebody to RTFM or STFW I usually have the page open in another tab/window of my browser,
so that I am sure that the information requested can be reached with a very small effort
enrico-sorichetti
Global moderator
 
Posts: 2644
Joined: Fri Apr 18, 2008 11:25 pm
Has thanked: 0 time
Been thanked: 130 times


Return to CLIST & REXX

 


  • Related topics
    Replies
    Views
    Last post