My apologies in advance if this is a very basic question/answer - I have searched, and am "old" learning for the first time and have found myself a little lost.
It's my first time coding, and basically I have an array (lets say fruits), I've been able to create it displaying the array and shuffling that array on click - which is exactly what I wanted (yay go me).
Now I am trying to have the ability to keep track of how many times I have clicked the shuffle button = before I either click reset, leave the page or refresh the page in which the counter resets.
This is where my trouble lays. I am having trouble 'inter-twining' the array how many times I have clicked shuffle into my code. Honestly, I am getting confused, with so many 'help blogs' who all have different ways of doing things and I'd truly TRULY appreciate any help to get me sorted.
This is my current code to produce the list of fruits and being able to display it on my page.
function shuffleArray(arr) {
for (let i = arr.length - 1; i > 0; i--) {
const r = Math.floor(Math.random() * (i 1));
[arr[i], arr[r]] = [arr[r], arr[i]];
}
return arr;
};
const array = ["Apple", "Pear", "Apricot", "Nashy", "Kiwi", "Watermelon"];
function printArray(arr) {
return arr.reduce((acc, n, i) => {
return acc.concat(i < arr.length - 1 ? `${n}\n ` : `${n}`);
}, '');
};
function shuffle() {
const copiedArr = array.map(n => n);
const shuffledArray = shuffleArray(copiedArr);
document.getElementById("array").innerText = printArray(shuffledArray);
}
function restore() {
document.getElementById("array").innerText = printArray(array);
}
restore();
<div >
<span id="array"><pre></pre></span>
</div>
<br>
<br>
<button onclick="shuffle()" value="randomize">Shuffle!</button>
<button onclick="restore()">Retore</button>
To be honest I have tried so many different things I am lost and confused. And so am hoping to start from scratch this is my code and I am trying to get a counter to keep track of every time I click shuffle that resets when Reset is clicked.
CodePudding user response:
The closure in JavaScript can be solution but it's a bit challenging to understand.
const add = (function () {
let counter = 0;
return function () {counter = 1;
return counter}
})();
// Call add() 3 times
add();
add();
add();
// the counter is now 3
The variable add is assigned to the return value of a self-invoking function.
The self-invoking function only runs once. It sets the counter to zero (0), and returns a function expression.
This way add becomes a function. The "wonderful" part is that it can access the counter in the parent scope.
This is called a JavaScript closure. It makes it possible for a function to have "private" variables.
The counter is protected by the scope of the anonymous function, and can only be changed using the add function.
CodePudding user response:
Here you go. While swahili geeks answer is correct. It is quite confusing for a learner.
So I took a different approach. You define a state object for your application and work upon it.
It would be nice to wrap the whole thing in a function to isolate the scope of declared functions and variables and not pollute the window, but you get there on your speed.
Also note how I am using a spread operator [...arr]
to clone an array. No need to .map(n => n)
const state = {
originalArray: ["Apple", "Pear", "Apricot", "Nashy", "Kiwi", "Watermelon"],
currentArray: ["Apple", "Pear", "Apricot", "Nashy", "Kiwi", "Watermelon"],
numberOfShuffles: 0,
};
const outputElement = document.getElementById("js-array");
const counterElement = document.getElementById("js-count");
function formatArray(arr) {
return arr.reduce((acc, n, i) => {
return acc.concat(i < arr.length - 1 ? `${n}\n` : `${n}`);
}, "");
}
function shuffleArray(arr) {
for (let i = arr.length - 1; i > 0; i--) {
const r = Math.floor(Math.random() * (i 1));
[arr[i], arr[r]] = [arr[r], arr[i]];
}
return arr;
}
function shuffle() {
const copiedArr = [...state.currentArray];
const shuffledArr = shuffleArray(copiedArr);
state.currentArray = shuffledArr;
state.numberOfShuffles ;
updateUi();
}
function restore() {
state.currentArray = [...state.originalArray];
state.numberOfShuffles = 0;
updateUi();
}
function updateUi() {
outputElement.innerText = formatArray(state.currentArray);
counterElement.innerText = state.numberOfShuffles;
}
updateUi();
<pre id="js-array"></pre>
<br />
<span id="js-count"></span>
<br />
<br />
<button onclick="shuffle()">Shuffle!</button>
<button onclick="restore()">Restore</button>