【问题标题】:SAS - hash tables and has_nextSAS - 哈希表和 has_next
【发布时间】:2013-02-22 17:36:23
【问题描述】:

我正在为以下问题寻找一个优雅的解决方案,这将有助于避免代码重复。你可以看到这一行:

put auction_id= potential_buyer= ;* THIS GETS REPEATED;

在此代码中重复:

data results;

  attrib potential_buyer length=$1;

  set auction;

  if _n_ eq 1 then do;
    declare hash ht1(dataset:'buyers', multidata: 'y');
    ht1.definekey('auction_id');
    ht1.definedata('potential_buyer');
    ht1.definedone();
    call missing (potential_buyer);
  end;


  **
  ** LOOP THROUGH EACH POTENTIAL BUYER AND PROCESS THEM
  *;
  if ht1.find() eq 0 then do;

    put auction_id= potential_buyer= ;* THIS GETS REPEATED;

    ht1.has_next(result: ht1_has_more);
    do while(ht1_has_more);
      rc = ht1.find_next();

      put auction_id= potential_buyer= ;* THIS GETS REPEATED;

      ht1.has_next(result: ht1_has_more);
    end;
  end;
run;

我已将上面的示例简化为一行,因为真正的代码块相当长且复杂。如果可能的话,我想避免使用%macro sn-p 或%include,因为我想将逻辑“保留在”数据步骤中。

以下是一些示例数据:

    data auction;
      input auction_id;
    datalines;
    111
    222
    333
    ;
    run;

    data buyers;
      input auction_id potential_buyer $;
    datalines;
    111 a
    111 c
    222 a
    222 b
    222 c
    333 d
    ;
    run;

【问题讨论】:

    标签: hashtable sas code-duplication


    【解决方案1】:

    我想通了。结果证明很简单,只是我的大脑有点麻烦:

    data results;
    
      attrib potential_buyer length=$1;
    
      set auction;
    
      if _n_ eq 1 then do;
        declare hash ht1(dataset:'buyers', multidata: 'y');
        ht1.definekey('auction_id');
        ht1.definedata('potential_buyer');
        ht1.definedone();
        call missing (potential_buyer);
      end;
    
    
      **
      ** LOOP THROUGH EACH POTENTIAL BUYER AND PROCESS THEM
      *;
      if ht1.find() eq 0 then do;
    
        keep_processing = 1;
        do while(keep_processing);
    
          put auction_id= potential_buyer= ;* THIS GETS DOESNT GET REPEATED ANYMORE =);
    
          ht1.has_next(result: keep_processing);
          rc = ht1.find_next();
        end;
      end;
    
    run;
    

    【讨论】:

      【解决方案2】:

      你可以这样解决....但是 Rob 的答案更好。

      data results;
      
       %Macro NoDuplicate;
        Put auction_id= potential_buyer= ; * No Longer Duplicated;
       %Mend noduplicate;
      
       attrib potential_buyer length=$1;
      
       set auction;
      
       if _n_ eq 1 then do;
        declare hash ht1(dataset:'buyers', multidata: 'y');
        ht1.definekey('auction_id');
        ht1.definedata('potential_buyer');
        ht1.definedone();
        call missing (potential_buyer);
       end;
      
       **
       ** LOOP THROUGH EACH POTENTIAL BUYER AND PROCESS THEM
       *;
       if ht1.find() eq 0 then do;
      
        %NoDuplicate
      
        ht1.has_next(result: ht1_has_more);
        do while(ht1_has_more);
         rc = ht1.find_next();
         %NoDuplicate
         ht1.has_next(result: ht1_has_more);
        end;
       end;
      
      run;
      

      【讨论】:

      • 同意该解决方案本质上没有任何问题 - 我只是想在 IDE 中保持代码格式良好(而不是在格式丢失的宏中)。正如我所提到的,那里的代码非常庞大和复杂,所以任何有助于提高可读性的小东西都会很好。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-21
      • 2019-10-16
      • 2019-01-24
      • 2018-10-13
      • 2023-03-31
      • 1970-01-01
      • 2016-08-04
      相关资源
      最近更新 更多