Search code examples
intersystems-cachemumpsintersystems-cache-studio

Character Counting within a loop


Instead of using hardcoded calls like I did in the code below, is it possible to have use a WRITE command within a For Loop to print out number of times each character is used? Below is what I have written, which will give me "A=n" but what I would like would be "A=n","B=n" etc without it being hardcoded.

 CHARCOUNT
 n str
 f  r !,"Enter patient's name: ",str q:str=""  d
 . s ^XPTNAME(str)=""
 w #
 f  s str=$O(^XPTNAME(str)) q:str=""  w !,"A = ",$L(str,"A") 
 q

Solution

  • Not sure exactly what you want to achieve but below some ideas.

    COUNT() N array,char,key S key="" F S key=$O(^ZNAME(key)) Q:key="" D ; loop through all keys . S char="" . F I=1:1:$L(key) D ; loop through all letters .. S char=$E(key,I) ; extract the letter .. S array(char)=$G(array(char))+1 ; increment count S char="" F S char=$O(array(char)) Q:char="" D . W char,"=",array(char),! Q

    Testing in GTM:

    GTM>ZWR ^ZNAME
    ^ZNAME("first,last")="Second Street"
    ^ZNAME("name,surname")="First Street"
    
    GTM>d COUNT^ZZTEST
    ,=2
    a=3
    e=2
    f=1
    i=1
    l=1
    m=2
    n=2
    r=2
    s=3
    t=2
    u=1
    

    Although if you have Mixed case it can get different than you expect:

    GTM>ZWR ^ZNAME
    ^ZNAME("FIRST,LAST")=""
    ^ZNAME("first,last")="Second Street"
    ^ZNAME("name,surname")="First Street"
    
    GTM>d COUNT^ZZTEST
    ,=3
    A=1
    F=1
    I=1
    L=1
    R=1
    S=2
    T=2
    a=3
    e=2
    f=1
    i=1
    l=1
    m=2
    n=2
    r=2
    s=3
    t=2
    u=1
    

    For this see the below code that may be specific to GTM ($ZCO function), also able to handle arrays or globals with limitation to single key/subscription:

    Code (Attention that using arrays with name of the variable used internally in this label will not work, example "array","char","key","upper","where" since they will be newed):

    COUNTV2(where,upper)
            N array,char,key
            I $G(where)="" Q
            ; loop through all keys
            F  S where=$Q(@where) Q:where=""  D
            .       S char=""
            .       S key=$E(where,$F(where,"("),$L(where)-1)
            .       I $E(key)="""" S key=$E(key,2,$L(key)-1)
            .       I $G(upper) S key=$ZCO(key,"U") ; Convert to uppercase
            .       F I=1:1:$L(key)  D              ; loop through all letters
            ..              S char=$E(key,I)        ; extract the letter
            ..              S array(char)=$G(array(char))+1 ; increment count
            S char=""
            F  S char=$O(array(char)) Q:char=""  D
            .       W char,"=",array(char),!
            Q
    

    Tested with global:

    GTM>ZWR ^ZNAME
    ^ZNAME("FIRST,LAST")=""
    ^ZNAME("first,last")="Second Street"
    ^ZNAME("name,surname")="First Street"
    
    GTM>D COUNTV2^ZZTEST("^ZNAME",1)
    ,=3
    A=4
    E=2
    F=2
    I=2
    L=2
    M=2
    N=2
    R=3
    S=5
    T=4
    U=1
    

    Tested with array:

    GTM>zwr array2
    array2(12)=""
    array2("First")=""
    array2("lasT")=""
    
    GTM>D COUNTV2^ZZTEST("array2",1)
    1=1
    2=1
    A=1
    F=1
    I=1
    L=1
    R=1
    S=2
    T=2
    

    Disabling force upper case:

    GTM>D COUNTV2^ZZTEST("^ZNAME",0)
    ,=3
    A=1
    F=1
    I=1
    L=1
    R=1
    S=2
    T=2
    a=3
    e=2
    f=1
    i=1
    l=1
    m=2
    n=2
    r=2
    s=3
    t=2
    u=1
    

    If you want additional logic to include only character A to Z:

    GTM>W $A("A")
    65
    GTM>W $A("Z")
    90
    GTM>S char=","
    
    GTM>I ($A(char)>64)&($A(char)<91) w char
    
    GTM>s char="A"
    
    GTM>I ($A(char)>64)&($A(char)<91) w char
    A
    GTM>S char="f"
    
    GTM>I ($A(char)>64)&($A(char)<91) w char
    
    GTM>s char="Z"
    
    GTM>I ($A(char)>64)&($A(char)<91) w char
    Z