简体   繁体   中英

JavaScript - IF statement inside FOR loop is outputting both options

I'm writing a function that searches an array from a prompt using an IF statement. So for I get the output I want if it is successful, but it also outputs the failure.

  // The array I'm searching through var statesArray = new Array(); statesArray['WI'] = "Wisconsin"; statesArray['MN'] = "Minnesota"; statesArray['IL'] = "Illinois"; // Now I'm trying to let the user search for the full state name from the two-letter abbreviation. var stateSearch = prompt("enter a two letter state abbreviation") for(var key in statesArray){ var value = statesArray[key] if(stateSearch == key){ alert(value); }else{ alert("try again"); } } 

So if I type "WI" in the prompt, I get "Wisconsin" and "try again".

Loop is not appropriate for this. Loop will check all values of array and check found or not for all.

 var statesArray = new Array(); statesArray['WI'] = "Wisconsin"; statesArray['MN'] = "Minnesota"; statesArray['IL'] = "Illinois"; // Now I'm trying to let the user search for the full state name from the two-letter abbreviation. var stateSearch = prompt("enter a two letter state abbreviation"); let searchObj =statesArray[stateSearch]; if(searchObj == null){ alert("try again"); }else{ alert(searchObj); } 

Your for loop isn't exiting after it has found a match. Either put it in a function and return when you find a match or break the for loop

for(var key in statesArray){
    var value = statesArray[key]
    if(stateSearch == key){
        alert(value);
        break;
    }else{
        alert("try again");
    }
}
function searchArray(arr){
  for(var key in arr){
    var value = arr[key]
    if(stateSearch == key){
        return value;
    }
   }
}

Note: Array was created to store a numbered list of elements. If you need to get values by keywords, it's better idea to use a common object instead:

 var statesArray = { WI: "Wisconsin", MN: "Minnesota", IL: "Illinois", null: "Cancelled!" }; var abbr = prompt("enter a two letter state abbreviation"); alert( statesArray[abbr] || "try again" ); // will return the value, if `abbr` key exists, // and "try again" if statesArray[abbr] returned `undefined` 

Instead of using a for loop, you could use:

var index = statesArray.indexOf(stateSearch);

which will set index to -1 if the value is not found, otherwise it will be set to the position in the array that the value was found.

Like some of the other comments and answers said, you're not breaking/exiting your loop early when a match is found, which is why you are continuing to iterate through even after you find the right value. Had you searched for MI , for example, you would see:

try again
Minnesota
try again

Firstly, it's generally considered a better practice, from a performance and ease of reading standpoint, to create Array literals than to use the JavaScript new keyword to create an Array instance.

Secondly, JavaScript does not technically allow for Associative Arrays (Hashes/HashMaps) (in other words, arrays with named indices). From the MDN Developer Documentation for Arrays:

Arrays cannot use strings as element indexes (as in an associative array) but must use integers. Setting or accessing via non-integers using bracket notation (or dot notation) will not set or retrieve an element from the array list itself, but will set or access a variable associated with that array's object property collection.

In your case, I would think a simple object or Map would suit you better. For Map :

// Define the Map.
const statesHashMap = new Map([
  ['WI', 'Wisconsin'],
  ['MN', 'Minnesota'],
  ['IL', 'Illinois']
]);

// You could also do:
statesHashMap.set('TX', 'Texas');

// Attain user input:
const stateSearchKey = prompt("Enter a two letter state abbreviation");

Then, to iterate over and find the right state, you'd have a few different options:

// Iterate with forEach.
statesHashMap.forEach((value, key) => {
  if (stateSearchKey === key) {
    console.log(value)
  }
});

// Iterate with for..of
for (const key of statesHashMap.keys()) {
  if (stateSearchKey === key) {
    const state = statesHashMap.get(key);
    console.log(state);
  }
}

The problem with the forEach method above is that you can't break out without throwing an exception, which makes the for..of loop likely more favorable for you. If you want to show a message to the user when they don't get a state, you could use break statements:

// Iterate with for..of
for (const key of statesHashMap.keys()) {
  if (stateSearchKey === key) {
    const state = statesHashMap.get(key);
    console.log(state);
    break;
  } else {
    console.log('Try again');
    break;
  }
}

Or, to make it look nicer and as a better programming practice, encapsulate the operation in a function and return early when needed:

// Iterate with for..of
const findStateByAbbreviation = abbrev => {
  for (const key of statesHashMap.keys()) {
    if (stateSearchKey === key) {
      const state = statesHashMap.get(key);
      return console.log(state);
    } else {
      return console.log('Try again');
    }
  }
}

findStateByAbbreviation(stateSearchKey);

You should probably also use .toUpperCase() on the input from the user to ensure you match the key WI (for example) if the user provides wi .

Be wary of browser compatibility with the Map option, however.

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM