Making this a loop without copy pasting over and over Javascript - javascript

message.channel.send(embed1).then((msgg) => setTimeout(() => {
const opponentData = userHit(opponentp, userPet.stats.strength, userPet, opponentPet, userp)
const userData = opponentHit(userp, opponentPet.stats.strength, userPet, opponentPet, opponentp)
if (opponentData.health >= 1) {
msgg.edit(opponentData.embed)
}
if (userData.health >= 1) {
msgg.edit(userData.embed)
}
}, 1000))
}
So ... I have this code, and I have been stumped for a few days. I need to loop these so they run one after the other until on hits 0 or lower without copy pasting them over and over. I need it to stop editing the message after it hits 0 or lower.

To loop this code you have to use simple do while method!Read more about this method here. Mozilla documentation is very helpful!I hope I helped you with this.Have a nice day!

Related

My IF can run without errors but it doesn't work

I'm having trouble trying to create an IF Scenario in my cypress.
What I'm trying to do right now is to change the DurationMinutes of my website's timesheet if the DurationHours is below the specific number. However the website I'm working on is wonky, unable to type numbers and instead only works by pressing the up arrow key to change the DurationMinutes.
cy.get('[ng-model="item.durationMinutes"]').each(($el, index) =>
{
let hours = cy.get('[ng-model="item.durationHours"]')
let n = hours.toString()
cy.get('[ng-model="item.durationMinutes"]').then(($hours) =>
{
if(n <= 10)
{
cy.get('[ng-model="item.durationMinutes"]')
.click().type('{uparrow}',{multiple:true, force: true})
}
})
});
Above is the code I've made to do the IF scenario. Although it runs in my program, it doesn't change the DurationMinutes within the specified conditions. How should I fix this?
I suppose that the field is not of type inputso type shouldn't work.
Replace
.type('{uparrow}',{multiple:true, force: true})
with
.trigger('keydown', { keyCode: 38, which: 38 })
to simulate pressing the up arrow

How do I change a single quote of an array.element (that is inside an object) into a double quote without creating a new array?

I was told to try and use a certain code for one of the problems I solved a while ago. I'm trying to figure it out but am coming up with nada.
Using replace(), map() etc..
This is all supposed to be done using replit and not changing the whole array as part of the 'For Fun' challenge.
const products = [
{
priceInCents: 3995,
},
{
priceInCents: 2500,
},
{
priceInCents: 8900,
},
{
priceInCents: 12500,
},
];
/* Now trying to use:
products[i].priceInDollars = $${(products[i].priceInCents * .01).toFixed(2)}
*/
/*
New
Code
*/
function addPriceInDollarsKeyToProducts(pricey)
{ for (let i = 0; i < products.length; i++)
{ for (let product = products[i];
product.priceInDollars = `$${(product.priceInCents * .01).toFixed(2)}`; )
break;
}
}
addPriceInDollarsKeyToProducts();
console.log(products)
Running this snippet btw makes it seem like it's okay.
For example: I want products[0].priceInDollars to be "$39.95",
but instead I get '$39.95',
Snippet runs it as "$39.95"
I'm not supposed to recreate the whole entire array.
If the code doesn't match the double quote requirements I get TypeError: Cannot read property '0' of undefined
edited for clarification purposes
Alright, a friend caught the problem.
I never reinserted my return like a dumb dumb.
Here I was going crazy trying to make a '"$39.95"' into a "$39.95" via replace(), map(), creating a replace function and what not when it was simply that I needed to add
return products;
at the end between the ending }

Konami Key Sequence Array.splice() explanation needed

I'm doing a Konami Code exercise in JavaScript and while I got it to work on my own, the answer makes no sense to me. Would someone care to explain?
My solution:
const pressed = [];
var secretCode = 'wesbos';
window.addEventListener('keyup', e => {
//My code
if (pressed.length < 6) {
pressed.push(e.key)
} else if (pressed.length === 6) {
pressed.shift()
pressed.push(e.key)
console.log(pressed)
}
//End my code
if (pressed.join('').toLowerCase() === secretCode) {
console.log("SECRET COMMAND ACTION CODE TRIGGERED! COMMENCE KAMEHAMEHA");
$.getScript('http://www.cornify.com/js/cornify.js', function() {
cornify_add();
$(document).keydown(cornify_add);
});
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
An answer from https://medium.com/#nikkoortega/key-sequence-detection-f90773e3aa60 which I don't understand:
const pressed = [];
const secretCode = 'wesbos';
window.addEventListener('keyup', e => {
//Answer code
pressed.push(e.key)
pressed.splice(-secretCode.length - 1, pressed.length - secretCode.length)
//End answer code
if (pressed.join('').toLowerCase() === secretCode) {
console.log("SECRET COMMAND ACTION CODE TRIGGERED! COMMENCE KAMEHAMEHA");
}
})
The point of the code is to create a queue, a FIFO structure.
Array#splice is a confusing in-place function that removes elements starting at the first parameter up to the second parameter, with negative indices wrapping. The third parameter optionally adds new elements but it's not used here.
In the solution, -secretCode.length - 1 is basically a constant, -7 if the length of the secret code is 6. This is totally pointless and can just be replaced with 0 since they're really trying to access the first element, which is what should be dequeued.
The second parameter is pressed.length - secretCode.length which takes the difference between the number of keys collected so far and the total length of the secret code. This is <= 0 up until the pressed queue exceeds the size of the secret code, at which point it's 1, meaning the first element is dequeued because the splice call will look like splice(0, 1). When splice is called with a negative number like splice(0, -1) or splice(0, 0) it doesn't have any effect.
Here's a simplified and annotated version:
const pressed = [];
var secretCode = 'wesbos';
window.addEventListener('keyup', e => {
pressed.push(e.key);
console.log(
"after push, before splice",
pressed + "",
pressed.length - secretCode.length
);
pressed.splice(0, pressed.length - secretCode.length);
console.log("after splice", pressed + "");
console.log("______________");
if (pressed.join('').toLowerCase() === secretCode) {
console.log("SECRET COMMAND ACTION CODE TRIGGERED! COMMENCE KAMEHAMEHA");
}
})
<p>type: "wesbos"</p>
My opinion is that splice should usually be avoided, especially when messing with negative indices and adding elements. It's linear, clever, hard to understand and you're usually using the wrong data structure if you have to pop elements out of the middle of an array.
I prefer your approach but I'd write it like:
const pressed = [];
var secretCode = 'wesbos';
window.addEventListener('keyup', e => {
pressed.push(e.key);
while (pressed.length > secretCode.length) {
pressed.shift();
}
if (pressed.join('').toLowerCase() === secretCode) {
console.log("SECRET COMMAND ACTION CODE TRIGGERED! COMMENCE KAMEHAMEHA");
}
})
<p>type: "wesbos"</p>
The while could be if since we know we're always adding 1 element, but it also doesn't really hurt to keep it while either -- the point is that it's enforcing dequeues until the queue is the same size as the target word.
One of the annoying things about JS is that it doesn't have a good builtin queue structure, so we have to shift() an array. This is still linear, but at least it communicates intent of implementing a queue more clearly than a splice that's always operating at index 0 and always removing no more than 1 element, in spite of negative indexing obfuscation.

Count messages from a channel

I would like to clean all my channels and and I'm getting there.
The problem is, it's very, very long ...
message.guild.channels.cache.forEach(c => {
if (c.isText()) {
let CompteurMessage = 0;
let CompteurSuppression;
c.messages.fetch().then(messages => {
messages.forEach(msg => {
msg.delete();
});
});
c.send(`Your server is the best, ${message.author}.`);
}
});
Do you have any idea how to go much faster, for example counting the number of messages in a channel ?
EDIT :
Now, I clone the channels but they change places ...
c.clone().then((clone) => {
clone.send(`Love ${message.author}.`);
const originalPosition = c.position;
c.delete();
clone.setPosition(originalPosition);
});
Channels n°3 and 4 change their place.
Thank you
Two ways to do this.
Cloning
You can clone the TextChannel using TextChannel.clone.
This stops you having the 14 day limitation using BulkDelete.
const newChannel = await message.channel.clone();
message.channel.delete();
newChannel.send('The channel has been purged.');
BulkDelete
You can delete all the messages in the last 14 days very easily.
await message.channel.messages.fetch();
const messageCount = message.channel.messages.cache.map(x => x).length;
message.channel.bulkDelete(messageCount, true);
Note: Not the most elegant solutions since it's late at night but this should help you out.

Not truly async?

I have a array of about 18 000 elements. I'm creating a map application where I want to add the elements when the user zooms in to a certain level.
So when the user zooms in under 9 I loop tru the array looking for elements that is in the view.
However, it does take some time looping thru the elements, causing the map application lag each time the user zooms out and in of "level 9". Even if there are no elements to add or not, so the bottleneck is the looping I guess.
I've tried to solve it by asyncing it like:
function SearchElements(elementArr) {
var ret = new Promise(resolve => {
var arr = [];
for (var i in elementArr) {
var distanceFromCenter = getDistanceFromLatLonInKm(view.center.latitude, view.center.longitude, dynamicsEntities[i].pss_latitude, dynamicsEntities[i].pss_longitude);
var viewWidthInKm = getSceneWidthInKm(view, true);
if (distanceFromCenter > viewWidthInKm) continue;
arr.push(elementArr[i]);
}
resolve(arr);
});
return ret;
}
SearchElements(myElementsArray).Then(arr => {
// ...
});
But its still not async, this method hangs while the for loop runs.
Because you still have a tight loop that loops through all the elements in one loop, you'll always have the responsiveness issues
One way to tackle the issue is to works on chunks of the data
Note: I'm assuming elementArr is a javascript Array
function SearchElements(elementArr) {
var sliceLength = 100; // how many elements to work on at a time
var totalLength = elementArr.length;
var slices = ((totalLength + sliceLength - 1) / sliceLength) | 0; // integer
return Array.from({length:slices})
.reduce((promise, unused, outerIndex) =>
promise.then(results =>
Promise.resolve(elementArr.slice(outerIndex * sliceLength, sliceLength).map((item, innerIndex) => {
const i = outerIndex * sliceLength + innerIndex;
const distanceFromCenter = getDistanceFromLatLonInKm(view.center.latitude, view.center.longitude, dynamicsEntities[i].pss_latitude, dynamicsEntities[i].pss_longitude);
const viewWidthInKm = getSceneWidthInKm(view, true);
if (distanceFromCenter <= viewWidthInKm) {
return item; // this is like your `push`
}
// if distanceFromCenter > viewWidthInKm, return value will be `undefined`, filtered out later - this is like your `continue`
})).then(batch => results.concat(batch)) // concatenate to results
), Promise.resolve([]))
.then(results => results.filter(v => v !== undefined)); // filter out the "undefined"
}
use:
SearchElements(yourDataArray).then(results => {
// all results available here
});
My other suggestion in the comment was Web Workers (I originally called it worker threads, not sure where I got that term from) - I'm not familiar enough with Web Workers to offer a solution, however https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers and https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API should get you going
To be honest, I think this sort of heavy task would be better suited to Web Workers

Categories

Resources