Trouble showing alert after iterating through an array - javascript

I have an input field where the user inputs their zip code which I then attempt to match to a zip code within an array. While the following works, I need it to actually show an alert dialog once saying that zip code wasn't found, however, it current pops up a lot even if the zip code is in the list.
Here's my snippet:
_zipcodeBtn.onclick = function(){
var userZip = _zipcode.value;
for (var i = 0; i < zipcode_list.length; i++) {
if (zipcode_list[i] === userZip) {
console.log('works');
break;
} else {
alert("repeating");
}
}
};
I want it to check if their zip is available without it also repeating the else statement multiple times. Whats the best way to prevent this?

There's an easier way to find an item in an array, by referencing the array's indexOf() method (docs).
if (zipcode_list.indexOf(userZip) != -1) {
//found - do something
} else
alert('Zip not found!');
As Angel Politis shows, you can also use includes() if you literally just want to know whether an item is in an array, not its actual position within it.
Sidenote: it's important to check against -1 when using indexOf() because it returns the index at which the search is found - or -1 if it's not. If the search is found at the first key, this is 0, and 0 is a falsy value, which can catch people out sometimes when they do things like this:
var arr = [1, 2, 3];
if (arr.indexOf(1))
alert('success');
else
alert('failed');
You'd think the success alert would fire here, but actually it'll be the failure alert, because indexOf() in this case returns 0, and 0 is a falsy value when it's interrogated in a condition.

There's no need to use a loop here. You can just say:
if (!zipcode_list.includes(userZip)) alert("Doesn't work!");
If you must use a loop, then just set a flag by default to false and then, if the zip is found set it to true. Then you can check it outside the loop:
/* Create a flag and set it by default to false. */
var found = false;
/* Loop */
for (var i = 0, l = zipcode_list.length; i < l; i++) {
if (zipcode_list[i] === userZip) {
/* Set the flag to true and stop the loop. */
found = true;
break;
}
}
/* Check whether the zip was found in the array. */
if (found) console.log("Works!");
else alert("Doesn't work!");

Related

Conditions proof confusing

Given is res[]:
for(let k = 0; k < res.length; k++){
if($("#getData").val().length == 20){
//if ((res[k]) != $("#getData").val()) helpText = "No match!";
// -- Tried this too and a several other options - foreach, else, else if e. g.
if(!((res[k]) == $("#getData").val()))
resText = "No match!";
if((res[k]) == $("#getData").val())
resText = "Success!";
$("#result").html(resText);
}
}
If the !((res[k]) == $("#getData").val()) - "false" condition is defined, it always only makes the first res[0] item within the array valid. This item is possible to proof correctly - The array donĀ“t iterate.
If the - "false" condition is not defined, all works fine if only the "true" condition is defined. But in this way there is no resText == "No match!";
What is wrong...?
As #charlietfl mentioned, you are looping across an array and updating the result text at each index. Because you are never stopping the looping process, what this really means is that you are only ever getting the result from the last item in the array. If your "Success!" value is item 14 in a 20 item array, your result will match and pass on that iteration, but then will be overwritten on the iterations for the next 5 items. If the very last item is a success condition you will always get "Success!" and if not you will always get "No match!" regardless of the other items in the list.
My assumption is that what you are looking to do is determine if one of the items in the array is a match, and if so you want "Success!" as the output. If so, I suggest:
const success = false;
const getDataVal = $("#getData").val();
if (getDataVal.length == 20) {
for(let k = 0; k < res.length; k++) {
if (res[k] == getDataVal) {
success = true;
break;
}
}
}
$("#result").html(success ? "Success!" : "No match!");
I restructured your code a bit here to help me understand it. Note that I did some optimizations to it:
Moved the $("#getData").val() operation out of the loop and stored to a variable since the value will not change. This simplifies the code and is much easier on the processor.
Moved the condition on the length check of the value outside the loop. The loop contents would only ever run whenever that condition is true, so it is better to wrap the loop in the condition so that it never runs at all if that condition fails.
Added a break; to the loop to stop the loop once a success condition is found
Moved the setting of the #result outside the loop. This only needs to be done once you know the answer and not at every iteration.
Use a ternary with a simple boolean instead of strings to know the status of the match and output the final string.
If my assumption is correct that you are really interested in knowing if any item in the array matches, then I suggest using the some method of the array to evaluate it. This is a bit more expressive and removes the need for the looping structure.
let success = false;
const getDataVal = $("#getData").val();
if (getDataVal.length == 20) {
success = res.some(function (val)) {
return val == getDataVal;
});
}
$("#result").html(success ? "Success!" : "No match!");

Using Javascript Array Filter method to apply logic [duplicate]

I have search through quite a lot of questions here, but havent found one that i think fits my bill, so if you know of one please link to it.
I have an array that i want to search through for a specific number and if that number is in the array, i then want to take an action and if not then another action.
I have something like this
var Array = ["1","8","17","14","11","20","2","6"];
for(x=0;x<=Array.length;x++)
{
if(Array[x]==8)
then change picture.src to srcpicture1
else
then change picture.src to srcpicture2
}
but this will run the lenght of the array and end up checking the last element of the array and since the last element is not 8 then it will change the picture to picture2.
Now i can see why this happens, i just dont have any ideas as to how to go about checking if an array contains a specific number.
Thanks in advance.
What you can do is write yourself a function to check if an element belongs to an array:
function inArray(array, value) {
for (var i = 0; i < array.length; i++) {
if (array[i] == value) return true;
}
return false;
}
And the just do:
var arr = ["1","8","17","14","11","20","2","6"];
if (inArray(arr, 8)) {
// change picture.src to srcpicture1
} else {
// change picture.src to srcpicture2
}
It's a lot more readable to me.
For extra points you can add the function to the array prototype like so:
Array.prototype.has = function (value) {
for (var i = 0; i < this.length; i++) {
if (this[i] === value) return true;
}
return false;
};
And then the call would be
if (arr.has(8)) // ...
Pushing this even further, you can check for indexOf() method on array and use it - if not - replace it with the code above.
P.S. Try not to use Array for a variable name, since it's reserved for the actual array type.
use this
http://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Array/IndexOf
ie version
https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Array/IndexOf#Compatibility
Why don't just you abort the loop when you find the right number :
for(x=0;x<=Array.length;x++)
{
if(Array[x]==8) {
//change picture.src to srcpicture1
break;
}
}
You could sort the array first then check the array only up to the point at which a number would be in the array, were it to exist.
If you have unique keys and a faster retrieval is what you care about a lot, you can consider using a map instead of an array (if there's a hard-bound case of using an array, then it won't work of course). If using a map, you just check "if( num in arr ) ".

slice different arrays and return selected values

I am working on a problem. I do not know the right question to ask in order to solve this problem. I have gotten what seems to be the required results but the verification problem for the solution does not work. I am not sure if I am solving it correctly. Basically I am given an array and I have to filter out elements from that array by slicing certain ingredients.
question: "We only use the elements that the instruction tells us to. So, we need to create a slice of the given array of elements (taken from the beginning) to resemble only the elements we are using. If the instruction doesn't say anything, we only take the first element."
var hammerIngredients = ['iron', 'granite', 'copper'];
var spearIngredients = ['iron', 'granite', 'copper'];
var panIngredients = ['iron', 'granite', 'copper'];
take(hammerIngredients); // returns ['iron']
take(spearIngredients, 2); // returns ['iron', 'granite']
take(panIngredients, 3); // return ['iron', 'granite', 'copper']
"If the instruction says to use more than the elements listed, we use all the elements in the array. If the instruction says to use no elements, we return an empty array."
var plateIngredients = ['iron', 'granite', 'copper'];
take(plateIngredients, 0); // returns []
So I have tried to do the program and I have done the following. It appears to work, but when I try to verify it I get that it is invalid.
function take(ingredients, slicer) {
if (arguments.length === 1) {
slicer = 1;
}
if (ingredients === hammerIngredients){
return ingredients.slice(0, slicer);
} else if(ingredients === spearIngredients) {
return ingredients.slice(0,slicer);
} else if (ingredients === panIngredients) {
return ingredients.slice(0,slicer);
} else if (ingredients === plateIngredients) {
return ingredients.slice(0,slicer)
} else {
return;
}
}
And I have no idea why. Help please!
you have no logic for if the slicer parameter is 0, in which case you need to return an empty array.
Put this line in there and it should work, based on the requirements you gave:
if (slicer === 0) {
return [];
}
You code currently only works if one of those three exact arrays are used. Does the verification code create and use only those arrays?
Your code does not need to be tied to existing ingredient arrays. After setting the default slicer value you can just:
return ingredients.slice(0,slicer);

Javascript: action when a string is not found in an array of objects (if statement)

var checkStore=function (book) {
for (var i=0; i<BookStore.length;i++) {
if (book==BookStore[i].title) {
var reply= prompt ('Want to add to your cart?'+ BookStore[i].title);
if (reply==='yes') {
Susan.cart.push(BookStore[i]);
}
}
}
}
How to add to my existing code "if the string is not found, then alert the user 'not found!'". Do I used [else] statement or begin a new one? It's not working correctly when I used else-if statement.
You might want to find the book first, then do your logic:
var checkStore = function(book) {
var found;
for (var i = 0; i < BookStore.length; i++) {
if (book == BookStore[i].title) {
found = BookStore[i];
break;
}
}
if (found) {
var reply = prompt ('Want to add to your cart?' + found.title);
if (reply === 'yes') {
Susan.cart.push(found);
}
} else {
alert('not found!');
}
}
var checkStore=function (book) {
if(BookStore.indexOf(book) < 0){
alert('hello, no book');
} else {
for (var i=0; i<BookStore.length;i++) {
if (book==BookStore[i].title) {
var reply= prompt ('Want to add to your cart?'+ BookStore[i].title);
if (reply==='yes') {
Susan.cart.push(BookStore[i]);
}
}
}
}
}
}
The other answers are totally valid. You can also just make return points which stop the execution of the function at logical endpoints.
var checkStore=function (book) {
for (var i=0; i<BookStore.length;i++) {
if (book==BookStore[i].title) {
var reply= prompt ('Want to add to your cart?'+ BookStore[i].title);
if (reply==='yes') {
Susan.cart.push(BookStore[i]);
return "book added to cart."
}else{
return "book found, but not added to cart."
}
}
}
return "bummer, book not found.";
}
alert(checkStore("book title"));
Fastest solution
This is the shortest way to take your exact existing code and add a few lines and solve this problem: How to add to my existing code "if the string is not found, then alert the user 'not found!'".
var checkStore=function (book) {
var bookWasFound=false; //Line added here
for (var i=0; i<BookStore.length;i++) {
if (book==BookStore[i].title) {
bookWasFound=true; //Line added here
var reply= prompt ('Want to add to your cart?'+ BookStore[i].title);
if (reply==='yes') {
Susan.cart.push(BookStore[i]);
}
}
}
if (!bookWasFound) { //Line added here
alert('Not found!'); //Line added here
} //Line added here
}
Explanation and alternatives
Why don't we use an else statement?
You ask, "Do I used [else] statement[...]?"
You do not. You can not! The reason is because the else part of an if-else statement is executed when the if part is not executed. So if we put that in our loop, every time we compare a book title to the string we're looking for, our else would be executed if the book title didn't match. We only want that to happen once.
It is somewhat difficult to think about this scenario without a concrete example, so I will show what happens if we use an if-else statement.
The code would look like this:
if (book==BookStore[i].title) {
...
} else {
alert('Not found!');
}
Imagine that our BookStore is populated with 3 books: "The C Programming language", "JavaScript: Pocket Reference", and "Everybody Poops".
If the checkStore function is passed in "JavaScript: Pocket Reference". Our loop will go like this:
As soon as we enter the loop, book would be equal to "JavaScript: Pocket Reference", and i = 0 so BookStore[i].title is the same as BookStore[0].title, and the 0th book's title is "The C Programming language".
So the line if(book==BookStore[i].title) { would compare "JavaScript: Poc..." to "The C Prog..." and evaluate to false.
Since the if evaulated to false, the else part gets executed. The else part is alert('Not found!').
Now, we have finished one iteration of our loop, and we compared the string passed in to the first book's title which didn't match, so we gave the alert. But we shouldn't have! If we just kept going, we would see that the second book's title matched, so we shouldn't have told the user that the book wasn't found. It is correct that the book wasn't found, yet, but we should have waited before we announced this to the user.
I may have went into great detail to explain my point, but I believe it is very important. This is one example of when it takes thinking like a programmer or thinking algorithmically to solve the problem.
You have to think about the problem and ask yourself, "How do we know if a book is in the list?". Well, a book is in the list if its title is the same as the title of any book in the list. Because we have to use the word any when we say "...any book in the list", we know that our algorithm must test every book in the list.
We can't tell the user that a book was found, or not found, until we have tested every book in the list, or in our BookStore. We can't tell the user that a book was found, or not found, until our loop has finished.
So what do we do?
You will see this situation over and over again during your programming experience. You need to iterate over a list, and determine if something is in the list.
You can't ever know until you've iterated over every single object in the list, but once you have, how do you know the answer?
The solution is to use what is commonly referred to in programming, a flag. A flag is a variable that has two possible states: true, or false, on or off, yes or no, 1 or 0. It doesn't matter what you call the states. At any time, the flag can only be in one of the two possible states.
We can use a flag by setting it to one state, usually false or 0, then looping through some list and if (...) we set it to true. Each iteration of the loop, if some condition is met, we set our flag to true, and at the end of the loop, we know that the condition was met at some point in the loop, if the flag is true.
The most common way to implement a flag, is to use a boolean variable. That is, a variable which can only be set to true or false. In Javascript, there isn't a boolean variable since any variable can be set to any value. So we just use a regular variable, but still only set it to true or false.
We do that like this:
var myFlag = false;
// OR
var myFlag = true;
So a simple usage of a flag could be to determine if there exists an even number in a given array.
Just like this:
var myArray = [1, 3, 5, 123, 125, 4, 89, 8, 10];
var hasEven = false;
for(var i = 0; i < myArray.length; i++) {
if( myArray[i] % 2 == 0 ) {
hasEven = true;
}
}
if(hasEven) {
alert('Found an even number!');
} else {
alert('Did not find an even number!');
}
Note that you can test the value of a boolean (true or false) variable with if(variableName), you don't have to include the == true like if(variableName == true).
Final implementation
Now we can use our flag to solve our original problem
var checkStore = function(book) {
var bookWasFound = false;
for (var i = 0; i < BookStore.length; i++) {
if (book == BookStore[i].title) {
// If we get in this loop, we must have found a match,
// so we should set our flag to true now
bookWasFound = true
var reply = prompt ('Want to add to your cart? ' + BookStore[i].title);
if (reply === 'yes') {
Susan.cart.push( BookStore[i] );
}
} // End of if statement for prompt
} // End of loop looking for book
if( !bookWasFound ) { // Same as if( bookWasFound == false )
alert('Not found!');
}
} // End of function
Using this flag allows us to keep the inside of the for loop very clean and organized, and handle the results outside of it.

Check if item already exists in json array by matching ID

So I've this shopping cart, as JSON.
[{"tuote":{"id":"2","name":"Rengas 2","count":16,"price":"120.00"}},{"tuote":{"id":"1","name":"Rengas 6","count":"4","price":"25.00"}},{"tuote":{"id":"4","name":"Rengas 4","count":"4","price":"85.00"}}]
Formatted here.
So, I want to prevent from having the same value in there twice, and match them by their ids.
This is my current solution (buggy as a cockroach, doesn't really do the job), as the only time it works is when the matching value is first in the JSON string.
for (var i = 0; i < ostoskori.length; i++) {
if (ostoskori[i].tuote.id == tuoteID) {
addToExisting(tuoteID, tuoteMaara); //this doesn't matter, it works.
break //the loop should stop if addToExisting() runs
}
if (ostoskori[i].tuote.id != tuoteID) {
addNew(tuoteID, tuoteNimi, tuoteMaara, tuoteHinta); //this doesn't matter, it works.
//break
//adding break here will stop the loop,
//which prevents the addToExisting() function running
}
}
ostoskori is the json if you're wondering. As you can probably see, for each item the JSON has inside it, the more times addNew() will run.
So basically, if the JSON has a value with the same id as tuoteID, addToExisting() should run. If the JSON doesn't have a value same as tuoteID, run addNew().
But how?
You could use some to check if the id already exists. The beauty of some is:
If such an element is found, some immediately returns true.
If you're catering for older browsers there's a polyfill at the bottom of that page.
function hasId(data, id) {
return data.some(function (el) {
return el.tuote.id === id;
});
}
hasId(data, '4'); // true
hasId(data, '14'); // false
So:
if (hasId(data, '4')) {
addToExisting();
} else {
addNew();
}
Fiddle

Categories

Resources