1

Here is my code:

if (state == 'AZ' || state == 'CO' || state == 'DC' || state == 'IA' || state == 'LA' || state == 'MN' || state == 'NC' || state == 'ND' || state == 'NM' || state == 'NV' || state == 'OR' || state == 'SC' || state == 'TN' || state == 'VA' || state == 'WA' || state == 'WI' || state == 'WY') {}

Is there an easier way to write this using an array? This works, but I want it to be cleaner!

jrutter
  • 3,173
  • 9
  • 42
  • 51

8 Answers8

4

You can use an object:

if ({AZ:1,CO:1,DC:1,IA:1,LA:1,MN:1,NC:1,ND:1,NM:1,NV:1,OR:1,SC:1,TN:1,VA:1,WA:1,WI:1,WY:1}[state] == 1) {

Edit:

You could also look for the string in a string:

if ("AZ,CO,DC,IA,LA,MN,NC,ND,NM,NV,OR,SC,TN,VA,WA,WI,WY".indexOf(state) != -1) {

(This of course assumes that the variable contains something reasonable, a value like "," would give a false positive.)

This happens to be even faster than the plain comparisons in most browsers: http://jsperf.com/test-regexp-vs-obj/3

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • Yeah this is a great way IMO, this guy http://snook.ca/archives/javascript/testing_for_a_v wraps that in a nice function as well making the call look cleaner. – Loktar Aug 25 '11 at 21:09
  • Very surprising no one else thought of using an object. Much quicker to check by key than looping through an array. –  Aug 25 '11 at 21:09
  • +1, this is the way I would have done it because it performs best at runtime (essentially a hash table lookup). – jfriend00 Aug 25 '11 at 21:12
  • @jfriend00: Yeah, but I'd put money on it taking longer to generate the hash values for the has table than to loop through an array of 17 elements. If this code was inside a loop you'd eventually break even, but it might take a while. – Roman Aug 25 '11 at 21:19
  • @R0MANARMY: To make a fair comparison you should also include the time it takes to create the array, which would be pretty much the same as creating the object, as arrays are also hash tables. – Guffa Aug 25 '11 at 21:26
  • 1
    Why guess when you can test? http://jsperf.com/test-regexp-vs-obj/2 plain if. Speed order: what OP hated is fastest, Object, Reg Exp, indexOf. – epascarello Aug 25 '11 at 21:33
  • And if, the comparison data structure is declared outside the function ahead of time (which is what you would do if you wanted max performance for calling the function multiple times), then the object method is massively faster on every browser I tried except Chrome where the "if" barely beats it. I guess we're seeing Chrome's interpreter do really well on the "if" code. But, otherwise, the object method is 2-20x faster (varies a lot by browser). Object is almost 10x faster than array in Chrome. See here http://jsperf.com/test-regexp-vs-obj/4 for yourself. – jfriend00 Aug 25 '11 at 22:16
  • I'd declare `var stateList = {"AZ" : true, "CO" : true, etc};` outside the function, then the if test just has to say `if (stateList[state]) {}`. But either way speed would not be my first concern because I try to keep most of my JavaScript in the "progressive enhancement" category and thus I wouldn't be likely to be doing anything so long and complicated that performance on any one function matters much. – nnnnnn Aug 25 '11 at 23:36
3

Regular Expression:

if(state.match(/^(AZ|CO|DC|IA|LA|MN|NC|ND|NM|NV|OR|SC|TN|VA|WA|WI|WY)$/)){
    //do whatever
}
epascarello
  • 204,599
  • 20
  • 195
  • 236
2

Push all your possibilities into an array and use indexOf to check is contained in.

Example:

if(['NA', 'NB', 'NC'].indexOf(state) > -1)
{
    // true
}

Or add contains and use it :

Array.prototype.contains = function(obj) {
    var i = this.length;
    while (i--) {
        if (this[i] === obj) {
            return true;
        }
    }
    return false;
}

if(['NA', 'NB', 'NC'].contains(state))
{
    // true
}
Arnaud F.
  • 8,252
  • 11
  • 53
  • 102
2

If you're using jQuery:

var states = ['AZ' ,'CO' ,'DC' ,'IA' ,'LA' ,'MN' ,'NC' ,'ND' ,'NM' ,'NV' ,'OR' ,'SC' ,'TN' ,'VA' ,'WA' ,'WI' ,'WY'];
if($.inArray('AZ',states)>=0){
    console.log('Hurrah');
}

If you're not you'll need your own function like the top answer to this question.

Community
  • 1
  • 1
Sam Martin
  • 1,238
  • 10
  • 19
  • @jrutter: Be sure to give the array a meaningful name, not just `states`, presumably there's a reason these are grouped together. – Roman Aug 25 '11 at 21:20
  • Im guessing I can just use an else to do something for those state values that don't match against my array? Correct? – jrutter Aug 25 '11 at 21:30
  • Amazing when the jQuery solution is selected when there was no jQuery tag. lol – epascarello Aug 25 '11 at 21:35
1
if ( ['AZ', 'CO', 'DC', 'And so on'].indexOf(state) != -1 ) {
    // do something
}

NOTE: indexOf is not supported in IE < 9. If you have to support those browsers, you can either use jQuery:

if ( $.inArray(state, 'AZ', 'CO', 'DC', 'And so on') != -1 ) {
    // do something
}

or manually extend the array prototype.

Joseph Silber
  • 214,931
  • 59
  • 362
  • 292
  • FYI: indexOf of arrays is not supported in all browsers. – epascarello Aug 25 '11 at 21:05
  • https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf <-- Include on browsers that dont support... but kind of defeats the purpose of the question overall I suppose. – Loktar Aug 25 '11 at 21:07
1

Hava at look at this javascript version of a contains function. Simply populate an array with your state codes and check using the function

http://css-tricks.com/snippets/javascript/javascript-array-contains/

JConstantine
  • 3,980
  • 1
  • 33
  • 46
0
var states=new Array("AZ", "CO", ...);
for (s in states) {
  if (state == s) {
    // do something
    break;
  }
}

is one way to approach it.

Jared Ng
  • 4,891
  • 2
  • 19
  • 18
0

If you use CoffeeScript, which generates JavaScript output, you can simply write

if state in ['AZ', 'CO', 'DC', 'IA', 'LA', 'MN', 'NC', 'ND', 'NM', 'NV', 'OR', 'SC', 'TN', 'VA', 'WA', 'WI', 'WY']
    ...
michel-slm
  • 9,438
  • 3
  • 32
  • 31