The case is:
function trocaPrimeiroEUltimo(array) {
array.array[0]
array.array[array.length - 1]
return array
}
I did this way, but it didn't work. I can't change the structure of the function, just what it's inside. Someone, could please help me?
Do you want to replace the last value with the first value?
if so, do:
temp = array[0]
array[0] = array[array.length-1]
array[array.length-1] = temp
That's a simple swap.
The syntax makes use of new ES6 capabilities (destructuring an array). This way the exchange can be done without a temporary variable.
The whole thing can even be done as a one-liner:
const arr=[7,8,9,10,11];
const swapFirstLast=(a,l)=>([a[0],a[l]]=[a[l=a.length-1],a[0]],a);
console.log(swapFirstLast(arr))
The use of the argument l is also something you probably would not do in a "real" application. I only went for it so I would not have to define the variable locally. l is assigned a value on the right hand side of the assignment expression. By the time the result needs to be stored l has been calculated and can also be used for addressing the right target element.
Related
hello friends I got a hard one and I'm a bit in a pickle
in my blackjack game I create images(of the cards) and the values come from the .PNG name from a list in an object. what I want to do is be able to create a class on those images to be able to use the classList.contain() method in a other function. it seems to work but the number doesn't increment every time I call the function. All the cards have the same class.
function showCard(activePlayer, card) {
if (activePlayer.score <= 20){
let cardImage = document.createElement("img")
function incrementNumber(number){
number = number++
return number
}
//increment the number of the class
cardImage.classList.add(`images${incrementNumber()}`)
cardImage.src = `images/${card}.png`
document.querySelector(activePlayer["div"]).appendChild(cardImage)
hitSound.play()
}
}
I know i most likely forgot a simple thing but i cannot put my finger on it.
I added a number in the ${incrementNumber(1)} still keeps giving me the same images class for all images. thank you for all you're help!
The ++ (increment) operator can be confusing sometimes.
In your case, you are using it, but you are also assigning its return value back to the number. The easiest solution is not doing that assignment (changing number = number++ for just number++)
It also looks like number should be a global variable, not a parameter passed to the incrementNumber function.
The more interesting part to the problem though, is why the code does not work. This is due to how the ++ operator works. When you place it after a variable name (eg number++) JavaScript will effectively do this:
var temp = number;
number = number + 1;
return temp;
It increments the number variable by 1, but it returns the previous value of the variable. In your case, when assigning the result of number++ back to number, the increment operation will basically be cancelled out.
Also, note that you can place the ++ operator before a variable name (like ++number). This will not return the original value of the variable, instead returning the new (incremented) value.
Add a global variable to your scope named number and set it to one. Then replace number = number++ with number++.
I haven't found this answer anywhere, and have been on the lookout for a few months, so my apologies if I'm overlooking something that should be obvious. Self-taught and came upon a rather vexing gap in my knowledge here.
In an rather complex yarn of connected pieces, I have two globally-scoped (basically static) variables and an array of character types outside of the main onclick function, as such:
var missingWut = ["child","spouse","talisman","relic","sock"];
var rdmmissingWut;
var pronounA = "he";
var charTypes = [
["goatherd",pronounA+" wants to find a missing goat","kind"],
["shepherd",pronounA+" wants to find a missing sheep","cruel"],
["detective",pronounA+" wants to find a missing "+missingWut[rdmmissingWut],"spidery"],
...,
..., //this goes on for awhile; the array is currently 500 items long and has way more subindexes than I wanted/needed to include in this example.
];
We've declared the variable names in the line above, but obviously rdmmissingWut is undefined at this point.
We then - for the sake of memory - go on to define rdmmissingWut inside the function, thereby updating its value from undefined to a random index number:
rdmmissingWut = Math.floor(Math.random()*missingWut.length);
rdmcharType = Math.floor(Math.random()*charTypes.length);
before assigning a random charType index to character 1 (char1).
var char1 = charTypes[rdmcharType];
My question is this -
Is there a way to update the variable value within the array - after I've updated the variable - without redefining the entire array?
One could obviously just reiterate the definition of the array, at which point it would update all variable values with their current value, but that seems really clumsy, cluttered and inefficient.
Another use case (with the same issue):
I want to use this same chartypes array to randomly roll a character type for character 2 (char2) - and eventually, char3 & char4, as well. But let's say char2 (or 3 or 4) is female. To do this, after char1 was defined, I would then need to update the value of pronounA to "she" and thereupon update the pronounA definition in every instance within the charTypes array before selecting a random charTypes index for her - correct? What is the best way to accomplish this? I'm sure there must be some elegant solution that I'm just ignorant of.
Thanks for your help.
You'll be needing to evaluate that variable every time you run through your array, so I'd recommend a placeholder that can be replaced with .replaceAll
var missingWut = ["child", "spouse", "talisman", "relic", "sock"];
var rdmmissingWut;
var pronounA = "he";
var charTypes = [
["goatherd", pronounA + " wants to find a missing goat", "kind"],
["shepherd", pronounA + " wants to find a missing sheep", "cruel"],
["detective", pronounA + " wants to find a missing _missingWut_", "spidery"]
];
function getMissingWut() {
return missingWut[rdmmissingWut || 0]; // this uses zero incase the value hasn't been updated
}
console.log(charTypes.flat().join("\n").replaceAll(/_missingWut_/g, getMissingWut()))
rdmmissingWut = 4
console.log(charTypes.flat().join("\n").replaceAll(/_missingWut_/g, getMissingWut()))
I searched for how to shuffle a deck of cards that I made and I found these lines but I can't understand...
is (this) that is written in the second line a js keyword or it't just a given name
how does m stores deck.length + i
what does m-- means at the end of the sixth line
what is the function of line no.8
shuffle() {
const { deck } = this;
let m = deck.length, i;
while (m) {
i = Math.floor(Math.random() * m--);
[deck[m], deck[i]] = [deck[i], deck[m]];
}
return this;
}
I know it's a lot to ask but I would appreciate your help
is (this) that is written in the second line a js keyword or it't just a given name
Yes, this is a keyword in JavaScript. I strongly suggest you google "this javascript" to learn how this works. It will take some time to get your head around.
how does m stores deck.length + i
I assume you are asking about let m = deck.length, i;. Notice there is a ,, not a +. m only stores deck.length. i is a separate variable that is declared on this line. I suggest you use the Chrome or Firefox developer tools to step through the code to inspect the value of m. If you are unfamiliar with these tools, you definitely need to learn about them and how to use them effectively, especially to debug your code.
what does m-- means at the end of the sixth line
-- is the post-increment operator. It decreases the value of m by 1 and stores that new value in m. The result after the subtraction is used in the rest of the expression. You can experiment with this operator in your own code or in the JavaScript console.
what is the function of line no.8
[deck[m], deck[i]] = [deck[i], deck[m]]; uses destructuring syntax to swap two values in the array. Again, you can use the debugger in the browser's developer tools to inspect the values of the variables to see what happens.
const and this are keywords
const and let are similar to var, except const cannot be assigned after initialization.
m stores only deck.length. i is another variable, declared by the let
m-- means decrementation, i.e. same as m = m-1 and it gives value of m after that calculation.
On line no.8 You can see destructuring assignment.
I'm creating a few specific functions for a compiler I'm working on, But certain restrictions within the compiler's nature will prevent me from using native JavaScript methods like Array.prototype.pop() to perform array pops...
So I decided to try and write some rudimentary pseudo-code to try and mimic the process, and then base my final function off the pseudo-code... But my tests seem to fail... based on the compiler's current behavior, it will only allow me to use array.length, array element assignments and that's about it... My code is below...
pop2 = function(arr) {
if(arr.length>0){
for(var w=undefined,x=[],y=0,z=arr.length;y<=z;y++){
y+1<z?(x[y]=arr[y]):(w=arr[y],arr=x);
}
}
return w;
}
Arr = [-1,0,1,2];
// Testing...
console.log(pop2(Arr)); // undefined... should be 2
console.log(Arr); // [-1,0,1,2]... should be [-1,0,1]
I'm trying to mimic the nature of the pop function but can't seem to put my finger on what's causing the function to still provide undefined and the original array... undefined should only return if an initial empty array is sent, just like you would expect with a [].pop() call...
Anyone have any clues as to how I can tailor this code to mimic the pop correctly?
And while I have heard that arr.splice(array.length-1,1)[0]; may work... the compiler is currently not capable of determining splice or similar methods... Is it possible to do it using a variation of my code?
Thanks in advance...
You're really over-thinking [].pop(). As defined in the specs, the process for [].pop() is:
Get the length of the array
If the length is 0
return undefined
If length is more than 0
Get the item at length - 1
Reduce array.length by 1
Return item.
(... plus a few things that the JavaScript engine needs to do behind the scenes like call ToObject on the array or ensure the length is an unsigned 32-bit integer.)
This can be done with a function as simple as the one below, there's not even a need for a loop.
function pop(array) {
var length = array.length,
item;
if (length > 0) {
item = array[length - 1];
array.length -= 1;
}
return item;
}
Edit
I'm assuming that the issue with the compiler is that Array.prototype.pop isn't understood at all. Re-reading your post, it looks like arrays have a pop method, but the compiler can't work out whether the variable is an array or not. In that case, an even simpler version of this function would be this:
function pop(array) {
return Array.prototype.pop.call(array);
}
Try that first as it'll be slightly faster and more robust, if it works. It's also the pattern for any other array method that you may need to use.
With this modification, it works:
http://jsfiddle.net/vxxfxvpL/1/
pop2 = function(arr) {
if(arr.length>0){
for(var w=undefined,x=[],y=0,z=arr.length;y<=z;y++){
if(y+1<z) {
(x[y]=arr[y]);
} else {
(w=arr[y],arr=x);
break;
}
}
}
return w;
}
Arr = [-1,0,1,2];
// Testing...
console.log(pop2(Arr)); // 2
The problem now is to remove the last element. You should construct the original array again without last element. You will have problems with this because you can't modify the original array. That's why this tasks are maded with prototype (Array.prototype.pop2 maybe can help you)
I'm trying to number objects, which can be added to a cart with drag'n'drop. So, this snippet should check the current number written in span.amountVal, and easily add ´+1´ to this number, but the result is always ´1´. When I uncomment the ´alert(i++);´, the snippet work like I want to. I'm confused, what is this about?
$.favList.find("div[data-asset-id="+ _itemID +"]").each(function() {
var i = $(this).find("span.amountVal").text();
// alert(i++);
$(this).find("span.amountVal").text(i++);
});
Thank you.
i++ first returns the value of i, then increments it. When you have the alert( i++ ) in place, the variable is already once incremented.
Put the ++ in front of the variable:
$(this).find("span.amountVal").text( ++i );
Or simply add one to it since you're discarding the variable right after:
$(this).find("span.amountVal").text( i + 1 );
you have a pre-increment/post-increment issue, the following change should solve it:
$.favList.find("div[data-asset-id="+ _itemID +"]").each(function() {
var i = $(this).find("span.amountVal").text();
$(this).find("span.amountVal").text(++i);
});
Pre-Increment adds one to i and then returns i while Post-Increment adds 1 to i after it has been returned.
Below is a similar post on StackOverflow touching on the topic:
post increment vs pre increment - Javascript Optimization
What are you guys doing? It SHOULDN'T read a SPAN's value, it's bad practice. Instead, it should read the items length (inside an object, for example) and then display it.