How to call identifier loop with nodejs - javascript

I'm trying to do this loop but there's something wrong.
Do I need to loop variable c also?
Just to explain, There's a table and child(i) changes every row.
SelectorT receives one sentence like: Now\nIs\n09:00\n4\n7
VariableM splits the sentence in array:
variableM[0] = Now
variableM[1] = is
variableM[2] = 09:00
variableM[3] = 4
variableM[4] = 7
So I need to return the first child(i), then run the next and return again.
const c = [1,2,3,4,5];
for (const property in c) {
const result = await page.evaluate(() => {
const selectorT = '#Main > div > div > div:nth-child(3) > div > div:nth-child('+i+') > section:nth-child(1) > div > div:nth-child(1)';
let variableM = document.querySelector(selectorT).innerText.split("\n")
let variableH = variableM[0];
let variableA[= variableM[1];
let variableT = variableM[2];
let variableS1 = parseInt(variableM[3]);
let variableS2 = parseInt(variableM[4]);
return {
variableH , variableA, variableT, variableS1, variableS2
}
})
console.log(result);
}

This doesn't look like a loop perhaps you mean for (i = 1; i < 5; i++)
there is a typo in this line let variableA=variableM[1];, also you are returning the values inside the loop they should be returned outside the loop

Related

Why is the textContent not being replaced but rather added to when function is clicked?

const passwordBoxLeft = document.getElementById('password-box--left');
const passwordBoxRight = document.getElementById('password-box--right');
let passwordLeft = [];
let passwordRight = [];
let passwordLength = 15;
function generatePassword() {
for (let i = 0; i < passwordLength; i++) {
let leftPW = characters[Math.floor(Math.random() * characters.length)];
let rightPW = characters[Math.floor(Math.random() * characters.length)];
passwordLeft.push(leftPW);
passwordRight.push(rightPW);
};
passwordBoxLeft.textContent = passwordLeft.join('');
passwordBoxRight.textContent = passwordRight.join('');
};
I have a simple frontend password generator that takes a characters array and generates 15 random characters from said array, pushes this into container arrays and these arrays are then displayed as textContent on the DOM.
Everything works well but for some reason, I am not understanding how to replace the textContent divs with a new rendition of a random password. Instead, the function is acting as if I have placed a += for textContent so it keeps joining on another 15 random characters and so on everytime it is clicked, rather than showing just a new set of 15 random characters. This is obviously not the intended behaviour.
I can't seem to workout what I am doing wrong exactly.
You are using .push() method which adds one or more elements to the end of Array. It will always return new length of the Array.
In your case - .push() is adding new generated array to previously modified array.
let passwordLeft = [];
let passwordRight = [];
let passwordLength = 15;
let characters = `abcdefghijklmnopqrstuvwxyz`;
function generatePassword() {
for (let i = 0; i < passwordLength; i++) {
let leftPW = characters[Math.floor(Math.random() * characters.length)];
let rightPW = characters[Math.floor(Math.random() * characters.length)];
passwordLeft[i] = leftPW;
passwordRight[i] = rightPW;
};
console.log(passwordLeft.join(""));
console.log(passwordRight.join(""));
}
generatePassword();

Can you use repeat() in this instance? JS

Hello I am working on a practice program for customers taking a position in line at a deli.
Except when I call the line() function it will end with the first name in the array.
// `The line is currently customer name
How would one allow that single string output to contain all the customers in my array?
//ex: `The line is currently customer1 customer2 customer3 etc...
I was thinking I could use the repeat function for this but am having trouble making it work.
Am I thinking about that wrong, or is there another method to do so? Thanks!
let deli = []
const line = (array) => {
if (array.length === 0) {
console.log(`The line is currently empty.`)
} else if (array.length > 0) {
let count = 0
for (let el in array) {
count++
let order = `${count}. ${array[el]}`
let greeting = console.log(`The line is currently: ${order}`)
return greeting
}
}
}
line(deli)
EDIT: Hello, sorry. People always get mad at me on here, I'm very new to programming and still figuring everything out.
Essentially I'm using this below function to push names into the array. And when you call line() it should show all the names added!
const takeANumber = (katzArr, customer) => {
let count = 0
katzArr.push(customer)
for (i = 0; i < katzArr.length; i++)
if (katzArr.length) {
count = katzArr.length
let greeting = console.log(
`Welcome ${customer}. You are number ${count} in line.`
)
return greeting
}
}
You can use .join() method. It works on arrays. So for example you have an array-
const customers = ['customer1', 'customer2', 'customer3']
customers.join(', ') would return customer1, customer2, customer3
Cheers
const animals = ['pigs', 'goats', 'sheep'];
const line = (array) => {
if (array.length === 0) {
console.log(`The line is currently empty.`)
} else if (array.length > 0) {
let count = [];
for(let i = 0; i < array.length; i++){
count.push(`${array[i]} ${i + 1}`)
}
console.log(`The line is currently ${count.join(',')}`)
}
}
line(animals)

Cannot access 'isColliding' before initialization/ divs colliding

I'm trying to make an egg catching game and found some code snippets online and wanted them to work together so the points go up by one when two divs are colliding. I am getting this error Cannot access 'isColliding' before initialization. Also I don't know if the div collision works since I can't test it because of the error, thanks in advance for any help!
Code:
let points = $('#points');
let countpoints = 0;
let overlap = isColliding("#basket", "#egg6");
if (overlap) {
function EggHitsBasket() {
countpoints++;
points.text("points:" + countpoints);
}
}
let isColliding = function (div1, div2) {
let d1Offset = div1.offset();
let d1Height = div1.outerHeight(true);
let d1Width = div1.outerWidth(true);
let d1Top = d1Offset.top + d1Height;
let d1Left = d1Offset.left + d1Width;
let d2Offset = div2.offset();
let d2Height = div2.outerHeight(true);
let d2Width = div2.outerWidth(true);
let d2Top = d2Offset.top + d2Height;
let d2Left = d2Offset.left + d2Width;
return !(d1Top < d2Offset.top || d1Offset.top > d2Top || d1Left < d2Offset.left || d1Offset.left > d2Left);
};
you're calling isColliding before it's been defined, it's the same that would happen in the following code snippet:
let x = y * 2
let y = 42
you need to either declare isColliding before you call it. Or use of a function declaration
function isColiiding(div1, div2) { ... }
rather than a function expression
let isColliding = function (div1, div2) { ... }

Array not being updated after switching indexs

I'm working on a visualizer for sorting algorithms. Everything is working as intended until I got to the Selection Sort. I understand that the Selection sort will make a pass and search for the MINIMUM value and then swap that the index that it started at in the array. However, each time it makes a pass, the i value doesn't change. I tested it by changing the color of the block the i index represents in my loop and it never changes, so the MINIMUM value just keeps switching to where ever the i is.
You can view my project here on GitHub Pages, just use the left Navbar to choose Selection Sort and you can see the problem I'm having. The bottom snippet is my swap function, it didn't do this with any of the other sort methods, only the selection sort.
Github Pages -- https://kevin6767.github.io/sorting-algorithm-visualization/
Selection function
async function selectionSort() {
let blocks = document.querySelectorAll('.block');
for (let i = 0; i < blocks.length; i++) {
// Assume a minimum value
let min = i;
for (let j = i + 1; j < blocks.length; j++) {
blocks[j].style.backgroundColor = '#FF4949';
blocks[min].style.backgroundColor = '#13CE66';
blocks[i].style.backgroundColor = 'orange';
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, frame_speed)
);
const value1 = Number(blocks[j].childNodes[0].innerHTML);
const value2 = Number(blocks[min].childNodes[0].innerHTML);
if (value1 < value2) {
blocks[min].style.backgroundColor = '#58B7FF';
min = j;
}
blocks[j].style.backgroundColor = '#58B7FF';
}
if (min !== i) {
let tmp = blocks[i];
blocks[i] = blocks[min];
blocks[min] = tmp;
await swap(blocks[i], blocks[min]);
blocks = document.querySelectorAll('.block');
}
// Swap if new minimun value found
blocks[i].style.backgroundColor = '#58B7FF';
}
}
Swap function
function swap(el1, el2) {
return new Promise((resolve) => {
const style1 = window.getComputedStyle(el1);
const style2 = window.getComputedStyle(el2);
const transform1 = style1.getPropertyValue('transform');
const transform2 = style2.getPropertyValue('transform');
el1.style.transform = transform2;
el2.style.transform = transform1;
// Wait for the transition to end!
window.requestAnimationFrame(function () {
setTimeout(() => {
container.insertBefore(el2, el1);
resolve();
}, 300);
});
});
}
I ended up fixing it. It seems that I had to take the Nodelist array I was getting from just .querySelectorAll and convert that into an array using .Arrayfrom() which was pretty simple after some googling. From then on I needed to figure out how to update the array each pass, which once again was as simple as just moving one index from another.
The interesting part of the answer was how I was going to update the Nodelist itself that way all my css code would still work (This is a sorting visualizer, so it would show you what element it was on and highlight it with a color). The answer however was right in front of me. Even though I turned the Nodelist array into a regular array, I was still able to apply styles to it. This meant I didn't have to mutate the Nodelist array at all and was just able to keep a seperate array within the function to work with.
PS. The algorithm did have a lot of trouble in the above snippet because I was comparing 2 strings in the if statement (value1 and value2) this is what caused a lot of the actual algorithm erroring and was simply fixed by adding a Number() function around my innerhtml code.
Selection
async function selectionSort() {
let blocks = document.querySelectorAll('.block');
let convertedBlocks = Array.from(blocks);
let len = convertedBlocks.length;
for (let i = 0; i < len; i++) {
let min = i;
for (let j = i + 1; j < len; j++) {
convertedBlocks[j].style.backgroundColor = 'red';
convertedBlocks[min].style.backgroundColor = 'green';
convertedBlocks[i].style.backgroundColor = 'orange';
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, frame_speed)
);
if (
Number(convertedBlocks[min].childNodes[0].innerHTML) >
Number(convertedBlocks[j].childNodes[0].innerHTML)
) {
convertedBlocks[min].style.backgroundColor = '#58B7FF';
min = j;
}
convertedBlocks[j].style.backgroundColor = '#58B7FF';
}
if (min !== i) {
let tmp = convertedBlocks[i];
convertedBlocks[i] = convertedBlocks[min];
convertedBlocks[min] = tmp;
await swap(convertedBlocks[i], convertedBlocks[min]);
}
convertedBlocks[min].style.backgroundColor = '#58B7FF';
convertedBlocks[i].style.backgroundColor = '#58B7FF';
}
}

Unique words counter using javascript

I want to make a function uniqueWordCount which can count all unique words in a string (words.txt). I should be able to get the answer after returning it, and I have done something like this now:
let fs = require('fs');
function run() {
let text = fs.readFileSync('./words.txt', 'utf8');
return uniqueWordCount(text);
}
function uniqueWordCount(str) {
let count = 0;
let set = new Set();
let words = str.split (' ');
for(let i = 1; 1 < words.length; i++){
set.add(str[i]);
count = set.size;
}
return uniqueWordCount;
}
module.exports.run = run;
split the string on spaces using split() and make it a set. Set will remove the duplicates. Return the size of the set using size()
function uniqueWordCount(str) {
let set = new Set(str.split(' '));
return set.size;
}
console.log(uniqueWordCount('as as de we re'))
An ES5 & ES6 compliant solution could be:
"aabc adsd adsd hasd"
.split(/\b(?:\s+)?/)
.reduce(function(ac,d,i){!~ac.indexOf(d) && ac.push(d);return ac;},[]).length //return 3
Here are 4 changes you have to make to get your uniqueWordCount function to work:
Start your for-loop at let i = 0, not let i = 1
1 < words.length will ALWAYS be true, creating an infinite loop. Replace 1 with i -> i < words.length
In your for-loop access words[i], not str[i] since words is your array of words, str is just your original string.
You're returning a variable uniqueWordCount which is a function, but you need to return count which is storing the size of your set.
Here is how your function should now look:
function uniqueWordCount(str) {
let count = 0;
let set = new Set();
let words = str.split (' ');
// 1. replace 'let i = 1;' with 'let i = 0;'
// 2. replace the second condition 1 < words.length with i < words.length
for(let i = 1; i < words.length; i++){
// 3. replace 'str[i]' with 'words[i]'
set.add(words[i]);
count = set.size;
}
// 4. change 'uniqueWordCount' to 'count'
return count;
}
Note: You can and probably should get rid of your count variable and just return set.size at the end of your function. Then you will be able to avoid updating count on every iteration of your for-loop as well. This change is not required but would make your function nicer. Here is how it would look:
function uniqueWordCount(str) {
let set = new Set();
let words = str.split (' ');
for(let i = 1; i < words.length; i++){
set.add(words[i]);
}
return set.size;
}
One final optimization would be similar to what #ellipsis mentioned - creating a Set immediately while splitting your str string. Like this:
function uniqueWordCount(str) {
// automatically populate your 'Set'
let set = new Set(str.split (' '));
// immediately return your set's size
return set.size;
}
Note: If you want to count unique words regardless of case, you can immediately do str.toLowerCase() in your uniqueWordCount function.
function uniqueWordCount(str) {
var i = [];
return str.split(' ')
.map( e => (i[e] === undefined) ? i[e] = 1 : 0)
.reduce((accumulator, currentValue) => accumulator + currentValue);
}
console.log(uniqueWordCount("ws ws ws we we wf h"));

Categories

Resources