/***************************************************************************************************************** SAS file name: single_key_change.sas File location: __________________________________________________________________________________________________________________ Purpose: To demonstrate how to detect single key changes in multi-key hash objects in SAS Author: Peter Clemmensen Creation Date: 08/07/2020 This program supports the blog post "Single Key Changes in Multi Key Hash Objects" on SASnrd.com *****************************************************************************************************************/ /* Partial key lookups are not allowed */ data _null_; dcl hash h(); h.definekey("k1", "k2"); h.definedata("d"); h.definedone(); k1 = .; k2 = .; d = .; h.add(key : 1, key : 2, data : 3); rc = h.check(key : 1); /* Partial key lookup - Not allowed! */ run; /* Example data */ data have; input k1 k2 d $; datalines; 2 2 b 2 3 c 2 1 a 3 1 a 3 2 b 1 3 c 1 1 a 1 2 b ; /* Bart"s key-jumper technique */ data _null_; dcl hash h(multidata:"Y"); h.definekey("k1", "k2"); h.definedata("k1", "k2", "d"); h.definedone(); dcl hash hh(multidata:"Y"); hh.definekey("k1"); hh.definedata("k2"); hh.definedone(); dcl hash hhh(); hhh.definekey("k1"); hhh.definedone(); dcl hiter i("hhh"); do until(eof); set have end=eof; h.add(); hh.add(); hhh.ref(); end; do while(i.next()=0); put "** New key **"; hh.reset_dup(); do while(hh.do_over()=0); rc = h.find(); output; put (k1 k2 d)(=); end; end; stop; run; /* Mark's DIF Function Technique */ data _null_; if 0 then set have; declare hash h (dataset:'have', multidata : "Y", ordered : "Y"); h.definekey('k1','k2'); h.definedata(all:'Y'); h.definedone(); declare hiter i ('h'); do while (i.next()=0); if dif(k1) then put "** New key **"; put (k1 k2 d)(=); end; stop; run; /* Hash of hashes technique */ data _null_; dcl hash hoh (); /* 1 */ hoh.definekey("k1"); hoh.definedata("h", "hi", "k1"); hoh.definedone(); dcl hiter i ("hoh"); dcl hash h; /* 2 */ do until (lr); /* 3 */ set have end=lr; if hoh.find() ne 0 then do; h = _new_ hash (multidata : "Y"); h.definekey ("k1", "k2"); h.definedata ("k1", "k2", "d"); h.definedone(); declare hiter hi ("h"); hoh.add(); end; h.add(); end; do while (i.next() = 0); /* 4 */ put "** New key **"; do while (hi.next()=0); put (k1 k2 d)(=); end; end; run;