Have an idea?

Visit Sawtooth Software Feedback to share your ideas on how we can improve our products.

Screening based on a large list of ZIP codes

In a previous study, we wanted to only allow respondents to continue if they were from a ZIP code among a list of ZIP codes. I found another forum post (https://sawtoothsoftware.com/forum/14004/zip-code-screening) that was helpful and I used this code:

Begin Unverified Perl
 
 my $i=1;

for($i=1; $i<=LISTLENGTH("zipList1"); $i++)
      {
       if (VALUE("Zip") eq LISTLABEL("zipList1",$i))
        {  
             ADD("zipList1",$i);
             last;
        }  
      }
 
End Unverified


This worked well except that our list had more than 1,000 ZIP codes and if a respondent entered a ZIP that was not on the list, it had to check every single ZIP in the list which could take up to 30 seconds in testing. Has anyone found a more efficient way to screen respondents based on a large list of ZIPs.

Also, the ZIPs are more or less random, so you cannot rely on patterns in the ZIP to make the search more efficient.
asked May 1 by andrew_mcginnis (125 points)
Hopefully this post will be helpful to you:

https://sawtoothsoftware.com/forum/18529
Thank you for responding, Zachary. I don't think the post you reference solves the efficiency issue. In fact, I think the code in my original post is more efficient than both of the solutions in your link because the one in my post will exit the for loop as soon as a ZIP code is found. I tried the code in my original post with a list of 2,500 ZIP codes and it took around 30 seconds if a respondent entered a ZIP not in the list (meaning the code iterated through every ZIP in the list).

One idea I had was to ask a respondent their state first, and then narrow the list of ZIP codes based on the state they enter, but I haven't thought through the details of this yet.
You might be surprised by the performance of hashes.

But if you require using code like what you have above, I would at least note the following:

* The ListLength and Value function calls are querying the database thousands of times despite them always returning the same value.  Call those once each before the loop.
* The many ListLabel calls are likely less performant than making a single ListLabelsArray call pre-loop and parsing the response.  You could optionally lessen the amount of parsing effort by writing your own database call rather than using ListLabelsArray.
* Assuming these zip codes are entirely numeric characters, the "==" operator will probably outperform the "eq" operator.
Ah, I see. I am new to Perl and I misunderstood the first solution you posted in the link you referenced in your first comment. I tested a few different ways of doing it and your hash solution is very efficient.

Your suggestions  about calling functions prior to the for loop also helped, but are still pretty slow.

The hash solution is definitely the way to go! Thank you so much!

Your solution to the original question

Please only use this to answer the original question. Otherwise please use comments.
Your name to display (optional):
Privacy: Your email address will only be used for sending these notifications.
Anti-spam verification:

To avoid this verification in future, please log in or register.
...