unshift and push inside a loop in Javascript, infinite loop javascript - javascript

I'm a beginner student and I'm try to get some information from "user" using the prompt() function, and then throw this information in an array. I need to use the loop FOR and the WHILE to solve this problem.
This is my code:
let allEmployeess = Number(prompt("How many employees in the company?"));
let employee = new Array(allEmployeess);
let contador = 1;
for (let i = 0; i <= employee.length; i++) {
let colaborador = {
name: prompt("Employee name:"),
salary: Number(prompt("What is the salary amount??"))
}
employee.unshift(colaborador);
}
This isn't working and I'm falling into an infinite loop.
I suppose this happens because the unshift(and push) method, return the new lenght of the array, and maybe I'm increasing the array leaving it always bigger than the counter.
What can I do to solve this?

You are looping through an array that you keep adding elements to, hence the infinite loop. Use the number of employees (scalar) in the for loop instead. Also, I created the colaborador object outside of the loop, so it only takes up one place in memory:
let allEmployeess = Number(prompt("How many employees in the company?"));
let colaborador = {};
let employee = [];
for (let i = 0; i < allEmployeess; i++) {
colaborador["name"] = prompt("Employee name:");
colaborador["salary"] = Number(prompt("What is the salary amount??"));
employee.unshift(colaborador);
colaborador = {};
}
console.log(employee);

The were a few minor mistakes in your code which I tried to address with comments:
let allEmployeess = Number(prompt("How many employees in the company?"));
let employee = new Array(allEmployeess);
let contador = {}; // better to have an empty object instead of 1 for readablity
for (let i = 0; i < employee.length; i++) { // when you are iterating an array, it should go from 0 to length -1
let colaborador = {
name: prompt("Employee name:"),
salary: Number(prompt("What is the salary amount??"))
}
employee[i] = colaborador; // instead of removing ith element, just update it with the new inputs
}

As you point out, you’re continuously adding to the length of the array so employee.length keeps increasing, hence the infinite loop.
It looks like what you want in your for loop conditional is i <= allEmployees rather than i <= employees.length as allEmployees is the total count of employees and will not change.

Related

Trying to push a pair of array values into a another array randomly without duplicates javascript

I'm trying to make an memory card game but this part is hard to figure out. I have an array with a deck of cards and I'm trying to select a specific amount cards in pairs randomly from the deck of cards and push them into the gameBoard array but I intitally keep getting duplicate of the pairs. Basically I trying to shuffle cards. I tried using a conditional statement but i dont know if this right way to go about this but it still doesnt work.
javascript
const deckOfCards = [
'card1',
'card2',
'card3',
'card4',
'card8',
'card9',
'card10',
'card11',
'card12',
'card13',
'card14',
]
let shuffle = deckOfCards[Math.floor(Math.random() * deckOfCards.length)];
let pair = [shuffle, shuffle]
let len = mode
for (let i = pair; i < deckOfCards.length; i++) {
if (gameBoard.indexOf(deckOfCards[i]) === -1) {
gameBoard.push(deckOfCards[pair])
}
}
console.log(gameBoard)
});
let gameBoard = []
just a thought: you can move the selected element to the back of the array and then randomly select stuff from a slice of the prior, unchanged array... just like array.slice(0, {a_number_here}.
something like this I guess (I cannot get your code working so this is not tested yet):
let shuffle = deckOfCards[Math.floor(Math.random() * deckOfCards.length - 5)]
name = deckOfCards.splice(shuffle, 1)
deckOfCards.push(name)
by the way if you can use libraries, just go for underscore.js and it would become very simple. just like this:
b = _.shuffle(deckOfCards).slice(0,5);
console.log(b)
you can also take a look at these repositories too (I haven't yet had the chance to take a look at them though but they kinda have a lot of stars so):
https://github.com/mmenavas/memory-game/blob/master/js/MemoryGame.js
https://github.com/code-sketch/memory-game
you can copy existing one to new one ex : const cloneSheepsES6 = [...sheeps];
then you can apply your condition without any duplications
This should give you an array of unique pair of cards.
const deckOfCards = [
"card1",
"card2",
"card3",
"card4",
"card8",
"card9",
"card10",
"card11",
"card12",
"card13",
"card14",
];
const randomArray = [];
let noOfPairs = 6; // No. of pairs required
while (noOfPairs) {
let randomNumber = Math.floor(Math.random() * deckOfCards.length);
if (randomArray.includes(randomNumber)) {
continue;
}
randomArray.push(randomNumber);
noOfPairs--;
}
randomArray.sort(() => 0.5 - Math.random());
const gameBoard = randomArray.map((item) => [
deckOfCards[item],
deckOfCards[item],
]);
console.log(gameBoard);

Trying to get a new array based on two older ones but I get the following error: .push is not a function

I am trying to create a new array based on two old ones. So I have storywords array, and unecessarywords array. And I want to make a new betterwords array based on taking out the unecessarywords from storywords. My code is as follows:
let betterWords = [];
for (let u_words_i = 0; u_words_i < unnecessaryWords.length; u_words_i++) {
for (let story_i = 0; story_i < storyWords.length; story_i++) {
if (storyWords[story_i] != unnecessaryWords[u_words_i]) {
betterWords = betterWords.push(storyWords[story_i]);
}
}
};
console.log(betterWords);
#ggorlen is right. You don't need to assign after pushing.
Also Just wanted to make a quick remark regarding your code. It could be improved to be much more readable like so:
const betterWords = storyWords.filter(word => !unnecessaryWords.includes(word));

Creating a leaderboard with Firebase

I'm trying to build a top 10 leaderboard using the Firebase Realtime DB - I am able to pull the top 10 ordered by score (last 10 due to the way firebase stores in ascending order) however when I attempt to place them in the page they all appear in key order.
If I was a betting man I'd guess it's to do with the for loop I have to create the elements - but I'm not good enough at Javascript to work out where the issue is I've spent the last 3 hours on MDN and W3Schools and I can't for the life of me work it out.
Either that or I need to run a For Each loop on the actual data query? but I feel like I could avoid that as I'm already collecting the score data so I could just arrange that somehow?
I was sort of expecting everything to appear in ascending order - meaning I would have to go back and prepend my JQuery but instead I've managed to accidentally create a new problem for myself.
Any suggestions will be GREATLY appreciated
Here is my current code:
var db = firebase.database()
var ref = db.ref('images')
ref.orderByChild('score').limitToLast(10).on('value', gotData, errData);
function gotData(data) {
var scores = data.val();
var keys = Object.keys(scores);
var currentRow;
for (var i = 0; i < keys.length; i++){
var currentObject = scores[keys[i]];
if(i % 1 == 0 ){
currentRow = document.createElement("div");
$(currentRow).addClass("pure-u-1-5")
$("#content").append(currentRow);
}
var col = document.createElement("div")
$(col).addClass("col-lg-5");
var image = document.createElement("img")
image.src=currentObject.url;
$(image).addClass("contentImage")
var p = document.createElement("P")
$(p).html(currentObject.score)
$(p).addClass("contentScore");
$(col).append(image);
$(col).append(p);
$(currentRow).append(col);
}
}
Use .sort() beforehand, then iterate over each score object to add it to the page:
function gotData(data) {
const scores = data.val();
const keys = Object.keys(scores);
const sortedKeys = keys.sort((keyA, keyB) => scores[keyB].score - scores[keyA].score);
const content = document.querySelector('#content');
sortedKeys.map(sortedKey => scores[sortedKey])
.forEach(scoreObj => {
const row = content.appendChild(document.createElement('div'));
row.classList.add('pure-u-1-5'); // better done in the CSS if possible
const col = row.appendChild(document.createElement('div'));
col.classList.add('col-lg-5');
const img = col.appendChild(document.createElement('img'));
img.src = scoreObj.url;
img.classList.add('contentScore');
col.appendChild(document.createElement('p')).textContent = scoreObj.score;
});
}
For loops have worse abstraction, require manual iteration, and have hoisting problems when you use var - use the array methods instead when you can.

javascript: array with unknown length and unknown index names

I am making a program of a football league.
A example of a league:
team1
team2
team3
I want to save (increase) number of players for each team like
var teamArray = [];
teamArray[team1] = 1;
teamArray[team2] = 2;
and I am doing in the body of some functions like:
function 1(){}
function 2(){}
function .(){}
function .(){}
function .(){}
function n(){}
but this works only when i "teach" javscript that the array is an integer array... with somethin like
teamArray[team1] = 0;
teamArray[team1] = teamArray[team1] + 1;
but the problem is every time when i come to one of my functions, i have to set my array element to 0 and that makes the whole calculation wrong...
Could anyone give me a hint please?
My Idea was to was to set each array element to 0 from the beginning, but i dont know at the beginning of my game how many teams i will have today, that why i implemented the array like:
var teamArray = [];
Use a JavaScript object instead. Something like:
var teamObject = {
team1: 3,
team2: 5,
team3: 7,
};
Or, perhaps an array of objects:
var teamArray = [
{ name: 'team1', players: 3 },
{ name: 'team2', players: 5 },
{ name: 'team3', players: 7 }
];
The object is easier to access if all you want is to get or set the number of players:
teamObject.team1 += 1;
but an array is easier to loop through and can be ordered:
for (var i=0,j=teamArray.length; i<j; i++) {
console.log(teamArray[i].name + " has " + teamArray[i].players + " players");
}
You can increment the number of team members by testing the current number first, and if it does not exist, you initialise it with 0 on the fly. All that can be done in one expression with a logical OR (||):
teamArray[team1] = (teamArray[team1] || 0) + 1;
This will not destroy the previous value you had and work like a simple + 1 in that case.
You should define your teamArray as object, although it will work with array as well (since that is an object as well):
teamArray = {}
The name is then of course a bit confusing, but I'll stick with it.
Whenever you need to iterate over the teams you have collected, then you can use a for loop like this:
for (var team in teamArray) {
console.log(team, teamArray[team]);
}
thanks for all your help!
I did it like this now:
var listItems = $("#teamsDropdown li");
listItems.each(function(idx, li) {
var team = $(li).text();
TeamPlayerQuantities[team] = 0;
});
and increasing the qnty of players wiht functions like:
function1(team){
TeamPlayerQuantities[team] ++;
}

Adding for loop results to an array and displaying sum of added elements after the last loop

I have to get some records based on weekly basis for the last weeks, and have to add values from records of one week to an array. So, I declared 6 arrays to store 6 weeks records. My code is:
var w_0 = [];var w_1 = [];var w_2 = [];var w_3 = [];var w_4 = [];var w_5 = [];
var myTotal = 0;
var arr_name = "";
for(var j=0;j<=5;j++)
{
var start_date="";
var end_date="";
//code to fetch the records added between start_date,end_date
//there may be more that one record
var count = getRecordCount(); //My function
//following loop is to fetch value from a record
for(var i=0;i<count;i++)
{
var val1 = getRecordByIndex(i).getValue("rem_val"); //getRecordByIndex() and getValue() are our pre-defined functions.
//here I want to push the values into the array w_0
arr_name = "w_"+j;
[arr_name].push(val1); //this is not working
alert([arr_name]); //showing 'w_0'
}
//and here I want to sum all the array elements when i reaches its maximum
for(var a=0;a<[arr_name].length; a++){
myTotal += parseInt([arr_name][a]);
}
alert("Total value of week"+j+"="+parseInt(myTotal));
}
How can I add values of inner loop to the array based on outer loop?
Any time you find yourself creating variables with sequentially numbered names, you should probably be using an array instead.
var w = [[], [], [], [], []];
Then, wherever you tried to use [arr_name] to refer to a particular w_j variable, you should use w[j].
for(var j=0;j<=w.length;j++)
{
var cur_w = w[j];
var start_date="";
var end_date="";
//code to fetch the records added between start_date,end_date
//there may be more that one record
var count = getRecordCount(); //My function
//following loop is to fetch value from a record
for(var i=0;i<count;i++)
{
var val1 = getRecordByIndex(i).getValue("rem_val"); //getRecordByIndex() and getValue() are our pre-defined functions.
cur_w.push(val1);
alert(cur_w);
}
//and here I want to sum all the array elements when i reaches its maximum
for(var a=0;a<cur_w.length; a++){
myTotal += parseInt(cur_w[a]);
}
alert("Total value of week"+j+"="+parseInt(myTotal));
}
If you want to dynamically manipulate global variables you can use window prefix:
arr_name = "w_"+j;
window[arr_name].push(val1); // This should work

Categories

Resources