Javascript program is not recognizing an if statement [duplicate] - javascript

This question already has answers here:
How to compare arrays in JavaScript?
(55 answers)
Closed 5 years ago.
The program is running an else statement when I'm expecting an if statement to run. When the program checks the gameObject's playerSelections property against the gameObject's colorSequence property I expect the program to log 'You got it. Way to go!' if the two arrays are equivalent. Instead I keep getting the console log statement 'Better luck next time!'. Does anyone have any ideas as to why this may be happening. `
const $headerText = $('.fly-in-text');
setTimeout(function() {
$headerText.removeClass('temp-hide');
}, 500);
let gameObject = {
colorIds: ['#blue', '#red', '#green', '#yellow'],
currentLevel: 1,
colorSequence: [],
playerSelections: [],
illuminate:function(color){
setTimeout(function(){
$(color).css('opacity', .5);
setTimeout(function() {
$(color).css('opacity', 1);
},500);
},500);
},
levelSequence: function(){
const iterationCount = this.currentLevel + 2;
for (let i = 0; i < iterationCount; i++) {
this.colorSequence.push(this.colorIds[Math.floor(Math.random() * 4)]);
}
this.startGame(this.colorSequence);
},
startGame: function(sequence) {
let i = 0;
const self = this;
var interval = setInterval(function(){
self.illuminate(sequence[i]);
i++;
if (i >= sequence.length){
clearInterval(interval);
}
}, 1000);
}
}
$circle.click(function() {
clearTimeout(interval);
$(this).toggleClass('rotate');
gameObject.levelSequence();
$('.colors').click(function(){
gameObject.playerSelections.push(`#${this.id}`);
console.log(gameObject.playerSelections);
checkForWin();
// for (let i = 0; i < gameObject.colorSequence.length; i++) {
// playerSelections[i] = (`$${this.id}`);
// console.log(playerSelections)
// }
})
})
function checkForWin(){
if (gameObject.playerSelections === gameObject.colorSequence){
console.log('Comparing')
if (gameObject.playerSelections === gameObject.colorSequence){
console.log('You got it. Way to go!');
gameObject.colorSequence = [];
gameObject.playerSelections = [];
gameObject.currentLevel += 1;
$('.colors').off('click');
return 'You got it. Way to go!';
} else {
gameObject.colorSequence = [];
gameObject.playerSelections = [];
$('.colors').off('click')
console.log('Better luck next time!');
}
}
}

Since playerSelections and colorSequence are arrays, your the condition gameObject.playerSelections === gameObject.colorSequence tests that the array references are equal, not the contents of the arrays.
You need to check that each element of the array is equal:
How to check identical array in most efficient way?

Related

How can i solve this exercixe with String.prototype?

How can i create this to console log like this?
String.prototype.sheldonize = function () {
return `knock ${this}`
}
'Penny'.sheldonize(3)
I have this code at the moment, but I dont know how to repeat knock more times
Use the repeat method to establish a number of 'knocks' in the line and to establish how many times the line should repeat
String.prototype.sheldonize = function (repeats) {
const line = `${'knock '.repeat(repeats)}${this}, `.repeat(repeats)
return `${line.substring(0,line.length-2)}.`;
}
console.log('Penny'.sheldonize(3));
Using For Loop and repeat method
String.prototype.sheldonize = function(count) {
let ans = "";
for (let i = 0; i < count; i++) {
ans += "knock ";
}
ans = `${ans}${this}, `.repeat(count)
ans = ans.substring(0, ans.length - 2) + "."
return ans;
}
console.log('Penny'.sheldonize(3))
console.log('Penny'.sheldonize(2))
Create an array and on each iteration up to n - 1 add the string to it, finally joining it up and returning the string from the function.
// If you're adding to a prototype it's always best
// to double check to see if the method already exists
// no matter (in this case) how unlikely
if (!('sheldonize' in String.prototype)) {
String.prototype.sheldonize = function (n) {
// Create the array
const out = [];
// Create the string
const knock = 'knock '.repeat(n);
// Loop until `n - 1` has been reached
// pushing the string into the array
// on each iteration
for (let i = 0; i < n; i++) {
out.push(`${knock}${this}`);
}
// Finally return the joined array
return out.join(', ');
}
}
console.log('Penny'.sheldonize(3));
console.log('Penny'.sheldonize(2));
console.log('John'.sheldonize(4));
Additional documentation
repeat

Default Javascript objects are very slow when large?

I am doing a modified version of collecting word co-occurrences, so I wrote my own javascript, and I am tracking the occurrences in three objects. However, once the objects get large (~8 million, 3 million, and 172000) a function that took 5 seconds per 100000 sentences now takes minutes to do one sentence with 30 words (30 tokens). I am nowhere near my RAM cap (I have 12 more GBs of RAM it could be using, and the program is only using 2.2GB). Using Node.js v17.3.1.
Why does my function take so long when the objects get bigger (even though the sentences remain the same length)? Should I be using a different object besides Javascript's default object, or is there a way improve the speed of access and setting these objects when they are so big?
Code:
let posCounts = {};
let negCounts = {};
// the number of times each word occurs
let wordCounts = {};
let tokens = // some function that gets tokens;
for (let k = 0; k < tokens.length; k++) {
// count word occurences
if (tokens[k] in wordCounts) {
wordCounts[tokens[k]] += 1;
} else {
wordCounts[tokens[k]] = 1;
}
for(let tok = k + 1; tok < tokens.length; tok++) {
if (tok == k) {
// avoid word to self cooccurrence
// should no longer be possible
continue;
} else {
// check which form of the cooccurence exists already in either count
actual_tok = (tokens[k] + "-" + tokens[tok]);
if(actual_tok in posCounts || actual_tok in negCounts) {
// no-op
} else {
actual_tok = (tokens[tok] + "-" + tokens[k]);
}
// condition set before this block of code
if(condition) {
if (actual_tok in posCounts) {
posCounts[actual_tok] += 1;
} else {
posCounts[actual_tok] = 1;
}
} else {
if (actual_tok in negCounts) {
negCounts[actual_tok] += 1;
} else {
negCounts[actual_tok] = 1;
}
}
}
}
}
Update: I've tried increasing the heap size via node train_matrices.js --max-old-space-size=12288 and node train_matrices.js --max_old_space_size=12288 (underline instead of dash), and that didn't work either.
Probably not the main issue in your code, but you can reduce the number of lookups by changing this structure from this:
if (tokens[k] in wordCounts) {
wordCounts[tokens[k]] += 1;
} else {
wordCounts[tokens[k]] = 1;
}
to this:
let token = tokens[k];
let cnt = wordCounts[token] || 0;
wordCounts[token] = cnt + 1;
And, as I said in a comment, I've read that a Map object with .get() and .set() is better suited when there are lots of dynamically created keys whereas plain objects are better suited when you have lots of objects with all the same keys (as the JS compiler can sometimes make a C-like struct for it), but this can't be done when you're regularly adding new keys.
The answer was to both use the increase memory flag node <YOUR_FILE_NAME>.js --max-old-space-size=12288 and change to using a Map instead of an object - thanks to #jfriend00 and #Norman Breau for the suggestions. That said, maps have a max capacity of 2^24 items or 1 GB, so I ended up using a modified version of the BigMap from this stackoverflow (modified to limit the total number of items still - ended up running completely out of RAM).
Modified code (you can replace BigMap with Map if you want):
let posCounts = new BigMap();
let negCounts = new BigMap();
let wordCounts = new BigMap();
let actual_tok;
tokens = // some code
// mark every cooccurrence
for (let k = 0; k < tokens.length; k++) {
// count word occurences
if (wordCounts.has(tokens[k])) {
wordCounts.set(tokens[k], wordCounts.get(tokens[k]) + 1);
} else {
wordCounts.set(tokens[k], 1);
}
for(let tok = k + 1; tok < tokens.length; tok++) {
if (tok == k) {
// avoid word to self cooccurrence
// should no longer be possible
continue;
} else {
// check which form of the cooccurence exists already in either count
actual_tok = (tokens[k] + "-" + tokens[tok]);
if(posCounts.has(actual_tok) || negCounts.has(actual_tok)) {
// no-op
} else {
actual_tok = (tokens[tok] + "-" + tokens[k]);
}
if(condition) {
if (posCounts.has(actual_tok)) {
posCounts.set(actual_tok, posCounts.get(actual_tok) + 1);
} else {
posCounts.set(actual_tok, 1);
}
} else {
if (negCounts.has(actual_tok)) {
negCounts.set(actual_tok, negCounts.get(actual_tok) + 1);
} else {
negCounts.set(actual_tok, 1);
}
}
}
}
}
}

Why aren’t my two values comparing correctly?

I have objects that I am trying to compare their values and make a function happen if one value is greater than the other. But My code seems to be wrong because even though the value is greater than the other, it still console logs "false" instead of true. I even console logged the value to check if it was greater and it was. Here's my code.
var clicks1 = 0;
function onClick() {
clicks1 += 1;
document.getElementById("clicks1").innerHTML = clicks1;
document.getElementById("clicks1").value = clicks1;
var clicks2 = 0;
function onClick() {
clicks2 += 1;
document.getElementById("clicks2").innerHTML = clicks2;
document.getElementById("clicks2").value = clicks2;
playbutton.onclick = function () {
const click1var = document.getElementById("clicks1").value
const click2var = document.getElementById("clicks2").value
console.log(click1var)    //Console shows 3
console.log(click2var)    //Console shows 1
if (click1var < click2var) {
console.log('true')
} else {
console.log('false')  //Console shows false.  
}
}
click1var is 3
click2var is 1
if (click1var < click2var){ // are you asking if 3 is lower than 1 (FALSE)
then it will go to the else.

Running Loop showing results [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
How can I use a loop to flip a coin 20 times, each time displaying the result of the flip as a string on the page? After the loop completes, I want to return the array with the result of each flip.
What I have so far:
function display20Flips() {
const results = [];
var i;
var results = '';
for (i = 0; i < 20; i++) {
}
const coin = {
state: 0,
flip: function() {
this.state = Math.floor(Math.random() * 2);
},
toString: function() {
if (this.state === 0) {
return Heads;
} else {
return Tails
}
},
toHTML: function() {
const image = document.createElement('img');
image.src = `$this.toString()}.png`
image.alt = this.toString()
return image;
}
};
function display20Flips() {
const results = [];
// 4. One point: Use a loop to flip the coin 20 times, each time displaying the result of the flip as a string on the page. After your loop completes, return an array with the result of each flip.
for (let i = 0; i < 20; i++) {
if(i%2){
results[i] = 'heads';
} else{
results[i] = 'tails';
}
console.log(results[i])
}
}
display20Flips();
function display20Images() {
const results = [];
// 5. One point: Use a loop to flip the coin 20 times, and display the results of each flip as an image on the page. After your loop completes, return an array with result of each flip.
}
You might want to create a FlipCoin function which determinates the value, call this function in a loop, storing the function result value in a variable, which you can print to screen and add to a results array.
something like this
// Returns 1 or 0, i.e. 1 = Head, 0 = Tail
function flipCoin() {
var flipValue = Math.floor(Math.random() * 100);
return flipValue % 2;
}
function main() {
let results = [];
for (cnt = 0; cnt < 20; cnt++) {
let result = flipCoin();
results.push(result);
console.log(result == 0 ? "Tail" : "Head");
}
console.dir(results);
}
main();
I believe you want something like this:
function display20Flips() {
var results = [];
for (let i = 0; i < 20; i++) {
if(i%2){
results[i] = 'heads';
} else{
results[i] = 'tails';
}
console.log(results[i])
}
}
display20Flips(); // for displaying in snippet code
Use Array(20) to create an array of size 20
Array.map to iterate through each element, use Array.fill to fill the array with null values else it will not iterate through.
Math.random()*10 to generate a random number between 0-10.
If the value is even then returned Head else Tails
function display20Flips() {
return Array(20).fill().map(e => Math.random()*10 & 1 ? 'Head' : 'Tails')
}
console.log(display20Flips())
Im not an expert but here it is :D
<!DOCTYPE html>
<html>
<body>
<script>
var results = [];
function display20Flips() {
for (var i = 0; i <20; i++ ){
var x = Math.floor((Math.random() * 2));
if(x == 0){
results[i] = "heads";
}else{
results[i] = "tails";
}
}
console.log(results);
}
display20Flips();
</script>
</body>
</html>

Counting elements in an array and comparing them, javascript [duplicate]

This question already has answers here:
Counting the occurrences / frequency of array elements
(39 answers)
Closed 6 years ago.
I'm trying to solve a problem using my very limited knowledge of Javascript.
I've tried to build a way to count the number of times a particular letter appears in an array and compare it to the number of times another letter appears in the same array.
I'm able to pass 3 out 4 tests and have re written the code many times trying as many methods as I know.
I realize that what I've done is not efficient...just working on problem solving with a weeks worth of skills.
Appreciate any input. Thanks.
function isValidWalk(walk) {
var north = new Object ();
var south = new Object ();
var east = new Object ();
var west = new Object ();
for (var i = 0; i <walk.length; i++){
if (walk[i] == "n")
{north.input = "x"}
}
for (var i = 0; i <walk.length; i++){
if (walk[i] == "s")
{south.input = "x"}
}
for (var i = 0; i <walk.length; i++){
if (walk[i] == "e")
{east.input = "x"}
}
for (var i = 0; i <walk.length; i++){
if (walk[i] == "w")
{west.input = "x"}
}
if (north.input == south.input && east.input == west.input && walk.length==10) {
return true;
}
else {
return false;
}
}
Here is how I would do it:
function isValidWalk(walk) {
var steps = {n: 0, s: 0, e: 0, w: 0};
for (var i=0, l=walk.length; i<l; i++) {
if (steps.hasOwnProperty(walk[i])) {
steps[walk[i]]++;
} else {
return false; // The element is not "n","s","e", or "w"
}
}
return (steps.n == steps.s && steps.e == steps.w && walk.length == 10);
}
console.log( isValidWalk(['n','n','n','s','n','s','n','s','n','s']) ); // returns false
console.log( isValidWalk(['n','n','n','s','s','s','n','s']) ); // returns false
console.log( isValidWalk(['n','gg','hh','s','s','s','n','s','n','n']) ); // returns false
console.log( isValidWalk(['n','n','n','s','s','s','n','s','n','s']) ); // returns true

Categories

Resources