How to set a button to execute a for loop? - javascript

My code starts on first item in the first array and iterate through the second array. If the first item in the first array is the same as the item in the second array the value is printed to the console. So in this snippet Nandos and KFC should print to console.
Then once the first item in the first array has been compared to all of the items in the second array we would move to the second item in the first array and compare it to all the items in the second array.
I want to execute the for loop once the button is clicked.
I tried to make the for loop a function and to execute the function once the button was clicked but nothing happened.
<button id="search">Search</button>
var restaurantsOne = ["Nandos", "King Rooster", "Chick-Fil-A", "Dominos", "KFC"];
var restaurantsTwo = ["Nandos","MacDonalds","Burger King","KFC","Pizza Hut"];
for (var i=0; i<=restaurantsOne.length; i++) {
for (var j=0; j<=restaurantsTwo.length; j++){
if (restaurantsOne[i] == restaurantsTwo[j]){
console.log(restaurantsOne[i]);
}
}
}
I would like the for loop to execute once the button was clicked

You haven't linked the button to the loop! Wrap the loop in a function and then add an 'onclick' handler to the button that references the loop function.
var restaurantsOne = ["Nandos", "King Rooster", "Chick-Fil-A", "Dominos", "KFC"];
var restaurantsTwo = ["Nandos","MacDonalds","Burger King","KFC","Pizza Hut"];
function compareArrays () {
for (var i = 0; i < restaurantsOne.length; i++) {
for (var j = 0; j < restaurantsTwo.length; j++){
if (restaurantsOne[i] == restaurantsTwo[j]){
console.log(restaurantsOne[i]);
}
}
}
}
<button id="search" onclick="compareArrays()">Search</button>
Also, it's worth mentioning that you should use i < restaurantsOne.length instead of i <= restaurantsOne.length because the array index starts from 0 and array[array.length] will actually refer to an index that doesn't exist.
ie.
restaurantsOne.length // 5
restaurantsOne[0] // Nandos
restaurantsOne[1] // King Rooster
restaurantsOne[2] // Chick-
restaurantsOne[3] // Dominoes
restaurantsOne[4] // KFC
restaurantsOne[5] // undefined

Related

Displaying DOM elements on the web-page while looping over them

I am working on a landing page. I have 3 article elements, each of them has the property “display: none” and a class 'art'. I want to display each of them while looping over them. They should appear successively: the previous ones must disappear at each iteration, that is why I have used var j in the code below. But JS code displays them after the whole process of looping is completed. How to deal with it? Here: https://codepen.io/user_jacob/pen/oNjqWGg.
Currently, I am doing it like this (which is not working):
function makeAppear() {
var j = list.length-1;
for (var i = 0; i < list.length; i++) {
list[i].style.setProperty('display', 'block');
list[j-1].style.setProperty('display', 'none');
}
}
In set interval don put () just write function name . For looping create one global index then hide all first then show indexed one.
let j=0;
function makeAppear() {
for (var i = 0; i < list.length; i++) {
list[i].style.setProperty('display', 'none');
}
list[j].style.setProperty('display', 'block');
if(j<2){ j++;}
else {j=0}
}
setInterval(makeAppear, 2000);

JavaScript - Looping array less than I should

I'm trying to loop an array which contains a list of elements returned by ClassName, but I can't loop all of them, because of the next situation:
var list = document.getElementsByClassName('class');
for (var i = 0; i < list.length; i++) {
var theClass = list[i].className; //once got list[i].
theClass = theClass.replace('class', '');
list[i].className = theClass; //twice got list[i].
}
If the size of the list is = 4, I just can loop two times, because I'm getting twice each position per loop. Do you know what I can do and why it happens? Thank you.
The data structure returned by getElementsByClassName is Array-like and dynamic based on the DOM. Once you replace the class on the list item in question, you end up losing an item per iteration.
To fix this, you can take a copy of the returned values first before operating on them, or work backwards.
Take a copy:
var list = document.getElementByClassName('class')
var realList = []
Array.prototype.push.apply(realList, list)
for (var i = 0; i < realList.length; i++) {
// do changes as you have already
}
Working backwards:
var list = document.getElementsByClassName('class')
for (i=list.length - 1; i >= 0; i--) {
// do changes to list[i]
}
Another poster briefly mentioned a while loop which also works, but then their answer disappeared (I don't want to take credit for this!):
var list = document.getElementsByClassName('class')
while (list.length != 0) {
// do changes to list[0]
}
If you write out what happens in your initial code, you can see the problem more clearly:
Iteration 1: i=0, list=[a,b,c,d], length = 4, list[i]=a
Iteration 2: i=1, list=[b,c,d], length = 3, list[i]=c
Before Iteration 3: list=[b,d], i=2, length = 2, loop breaks
Now writing out what happens when using the reverse loop:
Iteration 1: i=3, list=[a,b,c,d], length = 4, list[i]=d
Iteration 2: i=2, list=[a,b,c], length = 3, list[i]=c
Iteration 3: i=1, list=[a,b], length = 2, list[i]=b
Iteration 4: i=0, list=[a], length = 1, list[i]=a
All these solutions are variations on this solution of avoiding using i to reference the middle parts of the array-like result value of getElementsByClassName so that the dynamic nature of it is dealt with.

Check inside a loop that array has next element in Javascript/QML

I have an array items. I need to make sure that in the current iteration of the loop I can safely call the next item of the array
for(var i = 0; i < items.length; ++i) {
// do some stuff with current index e.g....
item = items[i];
// then do something with item # i+1
if(items[i+1]) {
//do stuff
}
}
Is this how it is done or if not how/what would be the better way?
P.S. I do not want to do a bound check
If you want to loop through every element except the last one (which doesn't have an element after it), you should do as suggested:
for(var i = 0; i < items.length-1; ++i) {
// items[i+1] will always exist inside this loop
}
If, however, you want to loop through every element -even the last one-, and just add a condition if there is an element after, just move that same condition inside your loop:
for(var i = 0; i < items.length; ++i) {
// do stuff on every element
if(i < items.length-1){
// items[i+1] will always exist inside this condition
}
}
if(items[i+1]) will return false (and not execute the condition) if the next element contains a falsey value like false, 0, "" (an empty String returns false).
Put a value check on variable i and make sure it is less than items.length-1 in order to safely access items[i+1].
for(var i = 0; i < items.length-1; ++i) {
if(items[i+1]) {
//do stuff
}
}
Drop the for loop and use array#forEach, and simply check whether a next value exists:
items.forEach(function (item, index) {
if (!items[index + 1]) return;
// do something with item and items[index + 1]
});

How to compare Array value to result of 'for' loop in javascript

I have an empty array (called zoomthumbsarray) which gets values pushed to it whilst a 'for' loop is running. This 'for' loop is checking if a thumbnail image is present in the backend against the particular product the user is viewing. If there is an image it gets added into a vertical slider. The current issue is there are non colour specific images (like lifestyle shots) that are being added into the slider multiple times.
So I need to check if the image found in the for loop is currently stored in the array. If it is present, the image has already been generated and I don't want it to get pulled into the slider again. If it hasn't then the image will get added.
Below is the code I am working on. I would presume indexOf would be used but can't get this to work.
Any help would be really appreciated.
var zoomthumbsarray = [] // Empty array which gets populated by .push below during loop
for (var i = 0; i < storeImgsArr.length; i++) { // storeImgsArr finds the quantity of attributes present against the product. This loops and increments counter if there is another attibute image
for (var e = 0; e < storeImgsArr[i].images.imgL.length; e++) { // Loop and increment counter if there is a Large image
zoomthumbsarray.push(storeImgsArr[i].images.imgS[e].slice(-16)); // Slices off last 16 characters of image path i.e. _navy_xsmall.jpg or 46983_xsalt1.jpg and pushes this into 'zoomthumbsarray' array
// if statement sits here to build the html to add the image to the slider
}
}
zoomthumbsarray = [] // Resets array to zero
ANSWER
As answered by Chris I used $.unique to only keep unique values in the array.
Then wrap an if statement around the code to build the thumb image html if the array === 0 or if the current image isn't already in the array.
Updated code below:
var zoomthumbsarray = [] // Empty array which gets populated by .push below during loop
for (var i = 0; i < storeImgsArr.length; i++) { // storeImgsArr finds the quantity of attributes present against the product. This loops and increments counter if there is another attibute image
if (zoomthumbsarray === 0 || zoomthumbsarray.indexOf(storeImgsArr[i].images.imgS[e].slice(-16)) < 0) { // If statement is true if array === 0 or if the current image isn't already in the array
for (var e = 0; e < storeImgsArr[i].images.imgL.length; e++) { // Loop and increment counter if there is a Large image
zoomthumbsarray.push(storeImgsArr[i].images.imgS[e].slice(-16)); // Slices off last 16 characters of image path i.e. _navy_xsmall.jpg or 46983_xsalt1.jpg and pushes this into 'zoomthumbsarray' array
zoomthumbsarray = $.unique(zoomthumbsarray); //Keeps only unique elements
// if statement sits here to build the html to add the image to the slider
}
}
}
zoomthumbsarray = [] // Resets array to zero
Some cheap and dirty ideas:
Using underscore/lodash:
zoomthumbsarray = _.uniq(zoomthumbsarray); //Keeps only unique elements
jQuery has one as well:
zoomthumbsarray = $.unique(zoomthumbsarray); //Keeps only unique elements
then you loop through the array and build HTML.
Update:
There's something a bit odd about the rest of the JS. Might this work (if you're using a new enough browser)?
var zoomthumbsarray = [];
storeImgsArr
.map(function(item) { return item.images.imgS; })
.forEach(function(imgS) {
zoomthumbsarray = zoomthumbsarray.concat(imgS.map(function(imagePath) {
return imagePath.slice(-16);
}));
});
zoomthumbsarray = $.unique(zoomthumbsarray);
I have tried indexOf (see first if statement below) but this doesn't work.
As #elclanrs said, indexOf does return the index in the array not a boolean. You only will need to see if it's >= 0 to test whether an image is already contained in the array.
var zoomthumbsarray = [];
for (var i = 0; i < storeImgsArr.length; i++) {
for (var e = 0; e < storeImgsArr[i].images.imgL.length; e++) {
var image = storeImgsArr[i].images.imgS[e].slice(-16);
if (zoomthumbsarray.indexOf(image) < 0) { // not yet in the array
zoomthumbsarray.push();
// and build the html to add the image to the slider
}
}
}
If you have really lots of images and notice this starts slowing the page down, then there are too many images in your page anyway. No, joke aside; …then check the optimisation by #Ivey.
instead of using an array you can use an object to store the images as keys and a dummy value (possibly true). then you can extract the keys from this object.
var images = {};
for (var i = 0; i < storeImgsArr.length; i++) {
for (var e = 0; e < storeImgsArr[i].images.imgL.length; e++) {
images[storeImgsArr[i].images.imgS[e].slice(-16))] = true;
}
}
var zoomthumbsarray = [];
for(var k in images) {
zoomthumbsarray.push(k);
// build the html to add the image to the slider
}
EDIT: Added build html comment

removing of array elements an issue

I have a situation where i add tables on a click of button and each table is stored in array. Now when i remove 2 or 3 tables, wrong index are being removed.
addTable: function (obj) {
for (var i = 0; i < obj.length; i++) {
// Adding of table
array.push(obj)
// delete code of the table
(function (i) {
deleteButton.addEventListener('click', function (e) {
array.splice(i, 1);
});
})(i);
}
}
The problem i am facing is the value of i is always zero. each time i click on the button a the addTable function is called and the counter is always zero and that is passed to the function(i) too.
Any ideas on how can keep track of different i or counter so that it deletes the correct index in the array
Here is an update
this is the sample object i am sending each time.
Each time i click on the Add Table button, the same object is being passed. Now i am having difficulty in keeping track of the index of each item.
Once you've removed one table, all other tables have moved and their indexes that you installed in the delete Buttons will be wrong now. When you remove items from the array, all indexes shift.
So, suppose you remove table 3. Then, you press delete for table 4. It's got an index of 4, but since you already removed table 3, it's in spot 3 in the array now (after the previous delete), not spot 4. But, you're code still has i==4 associated with that table and is trying to delete it here, but it's not there any more.
What you are doing is just not a good way to do this. If you want to expand further on what you're really trying to do, we can help with much better solutions.
Given the limited info we have so far, all I know of to do is to find the item in the array (wherever it might have moved to) and delete it from there.
addTable: function (obj) {
for (var i = 0; i < obj.length; i++) {
// Adding of table
array.push(obj)
// delete code of the table
(function (item) {
deleteButton.addEventListener('click', function (e) {
// search through the array to find where this item is
// and remove it from the array
for (var j = 0; j < array.length; j++) {
if (array[j] === item) {
array.splice(j, 1); // remove it
break;
}
}
});
})(obj);
}
}
I do not know about deleteButton, but in case that obj is array with only one element (length equals 1): [{....}] and array.push is native Array.prototype.push method then:
addTable: function (obj) {
// Adding of table
var index=array.push(obj);
// delete code of the table
deleteButton.addEventListener('click', function (e) { array.splice(index, 1); });
}
if obj.length is undefined i will allways be 0
further more, then i < obj.length return false and the for loop will never execute
if obj passed in is this object:
var addObjectResponse = [{...}];
then addObjectResponse is an array of 1, hence i will allways be 0
i = 0
obj.length = 1
i < obj.length => 0 < 1 => true once

Categories

Resources