How to delete an entry from my array in Javascript - javascript

This error kept troubling me for about 2 hours now... I'm making an idle game where you can have your own city and I'm making a building system right now, the problem is the game crashes whenever I delete from array (I have build queue which holds buildings to be built and then removes them) building from build queue. I tried .shift .pop .push .indexOf(0) === 0 and [0] === "" and .splice(1,1) it just comes up with like .splice is not a function or .pop is not a function for all of them.
Nothing worked. Please HELP!
if (buildValue === 100 && buildQueue.indexOf("house") === 0){
populationmax++;
// here i need a command that will remove first element from array called buildQueue.
buildValue = 0;
}

Removing From Array
if (buildValue === 100 && buildQueue.indexOf("house") === 0){
populationmax++;
buildQueue.splice(0, 1); //removes first element
buildValue = 0;
}
JS Snippet
x = [1, 2, 3];
alert(x); //1,2,3
x.splice(0, 1);
alert(x); //2,3
Adding To/Creating Array
First, you don't need to put a blank string inside the buildQueue array, this might actually cause problems later, just do this:
buildQueue = [];
Second, you are trying to add strings to your array as if it were a string, using +=. Doing this however, is turning your array into a string, which is why you're getting the warning about `.splice()' you need to add strings to your array like this:
buildQueue.push(someString);
This way buildQueue will remain an array of strings.

var buildValue = 0,
buildQueue = [""],
buildSpeed = 1/200;
if (buildQueue[0]){
buildValue += buildSpeed;
}
if (buildValue >= 100){
buildValue = 100;
}
if (buildValue === 100 && buildQueue.indexOf("house") === 0){
populationmax++;
buildValue = 0;
}
if (buildValue === 100 && buildQueue.indexOf("big house") === 0){
populationmax+=4;
buildValue = 0;
}
if (buildValue === 100 && buildQueue.indexOf("gold storage") === 0){
goldmax++;
buildValue = 0;
}
if (buildValue === 100 && buildQueue.indexOf("food storage") === 0){
foodmax++;
buildValue = 0;
}
if (buildValue === 100 && buildQueue.indexOf("wood storage") === 0){
woodmax++;
buildValue = 0;
}
if (buildValue === 100 && buildQueue.indexOf("stone storage") === 0){
stonemax++;
buildValue = 0;
}
if (buildValue === 100 && buildQueue.indexOf("iron storage") === 0){
ironmax++;
buildValue = 0;
}
buildSpeed = 0.2;
That is all i have to do with build. Also if you buy a building it will just add to array. eg gold storage will add buildQueue += "gold store"; And the spaces between lines inside ifs are supposed to have command that deletes the [0] element.

Related

FizzBuzz is it possible make my solution shorter?

I tried to make 3 conditions in one array.forEach, but this give me incorrect output. Is it possible to short my code to one array.forEach? Have 3 conditions inside it?
var array = []; // create empty array
for (var i = 1; i < 101; i++) {
array.push(i); // write in array all values of i, each iteration
}
array.forEach((number) => {
if (array[number] % 3 === 0 && array[number] % 5 === 0) {
array[number] = "FizzBuzz";
}
});
array.forEach((number) => { //
if (array[number] % 3 === 0) {
array[number] = "Fizz";
}
});
array.forEach((number) => {
if (array[number] % 5 === 0) {
array[number] = "Buzz";
}
});
for (let i = 0; i < array.length; i++) { //output array elements
console.log(array[i]);
}
First pointer: that's a lot of whitespace.
Second pointer, rather than creating an array then cycling through that array, you can do it all in one loop, using the if....else block; something like this:
for (var i = 1; i < 101; i++) {
if (i % 3 === 0 && i % 5 === 0) {
console.log("FizzBuzz");
}
else if (i % 3 === 0) {
console.log("Fizz");
}
else if (i % 5 === 0) {
console.log("Buzz");
}
else {
console.log(i);
}
}
You are "walking over" the Array multiple times.
IMHO the most important Array Method to learn is Map:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
Which "walks over" the Array and returns a new value for that Array index
let arr = Array(100)
.fill((x, div, label) => x % div ? "" : label) //store Function in every index
.map((func, idx) =>
func(++idx, 3, "Fizz") + func(idx, 5, "Buzz") || idx
);
document.body.append(arr.join(", "));
fill takes a single Object, it is not executed 100 times!
Since JavaScript Functions are Objects this code declares a function once
Note the ++idx because we want to start at 1, not 0
In JavaScript ""+"" is a Falsy value, thus it returns the idx value for non-FizzBuzz numbers
More Array Methods explained: https://array-methods.github.io

Why code works when I write myArray[i] and not when I save myArray[i] in a variable?

I want to populate an empty array with the classical fizzbuzz game (numbers from 1 to 100, when a number is divisible by 3 print 'Fizz, divisible by 5 print 'Buzz', divisible by both 3 and 5 print 'Fizzbuzz'). The problem is, when I write code like in the first portion of code below saving my array[i] in a more convenient variable my if-else if statement doesn't work, only normal numbers are printed; but when I use array[i] instead of a variable everything works fine, as you can see in the second portion of code, where 'Fizz', 'Buzz', 'FizzBuzz' overwrite the normal numbers. They should be the same thing right?
First portion of code with a variable instead of array[i]
var numberArray = [];
var number = 0
for (var i = 0; i < 100; i++) {
number += 1;
thisNumber = numberArray[i];
numberArray.push(number);
if (number %3 ==0 && number %5 ==0) {
thisNumber = 'FizzBuzz';
} else if ( number %3 ==0 ) {
thisNumber = 'Fizz';
} else if ( number %3 ==0 ) {
thisNumber = 'Buzz';
}
}
console.log(numberArray);
Second portion of code with array[i] instead of a variable
var numberArray = [];
var number = 0
for (var i = 0; i < 100; i++) {
number += 1;
numberArray.push(number);
if (number %3 ==0 && number %5 ==0) {
numberArray[i] = 'FizzBuzz';
} else if ( number %3 ==0 ) {
numberArray[i] = 'Fizz';
} else if ( number %3 ==0 ) {
numberArray[i] = 'Buzz';
}
}
console.log(numberArray);
Reassigning a variable, by itself, never has any side effects (except in the most rare situations which aren't worth worrying about). Doing thisNumber = 'FizzBuzz'; does not change anything about how thisNumber may have happened to be used in the past.
Push after assigning to thisNumber. You also want to push thisNumber, not number.
You also need to change the final % 3 to % 5 - you're currently testing % 3 twice.
var numberArray = [];
for (var i = 0; i < 100; i++) {
let thisNumber = i;
if (i % 3 == 0 && i % 5 == 0) {
thisNumber = 'FizzBuzz';
} else if (i % 3 == 0) {
thisNumber = 'Fizz';
} else if (i % 5 == 0) {
thisNumber = 'Buzz';
}
numberArray.push(thisNumber);
}
console.log(numberArray);
In JavaScript a variable is just a reference to an object and an assignment changes where it points to. In
thisNumber = 'FizzBuzz';
you create a new string object and reference it with thisNumber. In
numberArray[i] = 'FizzBuzz';
you modify the i-th element of the array numberArray.
You can't create a reference to an array element and modify it with an assignment. That's not possible in JavaScript.

targeting the last item in an array in javascript

I got a function that's half working:
function prevTrack() {
if (playlist_index == (playlist.length - 0)) {
playlist_index = -1;
} else {
playlist_index--;
}
playlist_status.innerHTML = playlist[playlist_index];
audio.src = dir + playlist[playlist_index] + ext;
audio.play();
}
I'm sure the error is in the playlist_index = -1;
can anyone please tell me how to target the last item in the array?
so it would be playlist_index = ???;
Setting the index to -1 to get the last element reminds me of python ... in any case that doesn't work in JS. You have to set the index to playlist.length - 1.
i think playlist_index = playlist.legth - 1
Do you want to set the playlist_index to the last item in the array if the index is zero or the first item in the array?
const playlist_index = playlist_index === 0
? playlist_index = plalist.length - 1
: playlist_index--;
or
const playlist_index = playlist_index === firstValueOfArray
? playlist_index = playlist.length - 1
: playlist_index--;
It looks like you're trying to make the index go "around the world" so to speak. There is an easy way to do that with the modulo % operator.
const list = ['a', 'b', 'c']
for (let offset = 0; offset < 10; offset++) {
const item = list[offset % list.length];
console.log(item);
}
so you can replace
if (playlist_index == (playlist.length - 0)) {
playlist_index = -1;
} else {
playlist_index--;
}
with
playlist_index = (playlist.length + playlist_index - 1) % playlist.length;

Pushing data into object clears the other values

I'm making trying to push data into an object, but as soon as I push data to userID.name, the value of userID.age gets reset(?) in the console. Here's my code:
if (input.indexOf("ben") >= 0){
var slot = splitInput.indexOf("ben");
console.log(slot)
i = slot + 1;
if (splitInput[i].indexOf(0) >= 0 || splitInput[i].indexOf(1) >= 0 || splitInput[i].indexOf(3) >= 0 || splitInput[i].indexOf(4) >= 0 || splitInput[i].indexOf(4) >= 0 || splitInput[i].indexOf(5) >= 0 || splitInput[i].indexOf(6) >= 0 || splitInput[i].indexOf(7) >= 0 || splitInput[i].indexOf(8) >= 0 || splitInput[i].indexOf(9) >= 0){
i = 0;
var slot = splitInput.indexOf("ben");
// console.log(slot)
i = slot + 1;
userID.age = splitInput[i];
console.log(userID);
} if (splitInput[i].indexOf("a") >= 0 || splitInput[i].indexOf("e") >= 0 || splitInput[i].indexOf("i") >= 0 || splitInput[i].indexOf("u") >= 0){
i = 0;
var slot = splitInput.indexOf("ben");
// console.log(slot)
i = slot + 1;
userID.name = splitInput[i];
console.log(userID);
}
}
Here's my splitInput:
var splitInput = input.split(" ");
input is gathered through a getElementById function.
When I manually log userID I get this error VM935:1 Uncaught ReferenceError: userID is not defined(…) which may have something to do with it, although console.log(userID) works fine.
If you need more information, please let me know.
Thanks in advance!
Before assigning to an object property, like UserID.age, you must first have defined UserID itself.
So put this before you access a property of UserID:
var userID = {};
Remarks on the code
The way you check for numbers and words with vowels is not really that nice. It has a lot of repetitive code. Also inside the if blocks you were searching again for the word "ben", while you had that already done... Seems unnecessary to do that again.
Have a look at this version of your code:
// Sample data
var input = 'ik ben 51 jaar';
var splitInput = input.split(" ");
// This was missing:
var userID = {};
// Move retrieval of slot before the `if` so it can be reused
var slot = splitInput.indexOf("ben");
if (slot >= 0){
console.log('slot:', slot);
i = slot + 1;
// Make sure you are not at the end of the array, and
// use a regular expression to see next word consists of digits only
if (i < splitInput.length && splitInput[i].match(/^\d+$/)){
// convert the word to number with unitary plus:
userID.age = +splitInput[i];
}
// You'll maybe want to do an else here.
// Use regular expression again; don't forget the "o"
else if (i < splitInput.length && splitInput[i].match(/a|e|i|o|u/)){
userID.name = splitInput[i];
}
console.log(userID);
}

Determine Document Order from Nodes

If I have two nodes in an HTML document, how can I tell which one comes first in HTML document order in Javascript using DOM methods?
For example,
function funstuff(a, b) {
//a and b can be any node in the DOM (text, element, etc)
if(b comes before a in document order) {
var t = b; b = a; a = t;
}
// process the nodes between a and b. I can handle this part
// when I know that a comes before b.
}
Resig to the rescue:
// Compare Position - MIT Licensed, John Resig
function comparePosition(a, b){
return a.compareDocumentPosition ?
a.compareDocumentPosition(b) :
a.contains ?
(a != b && a.contains(b) && 16) +
(a != b && b.contains(a) && 8) +
(a.sourceIndex >= 0 && b.sourceIndex >= 0 ?
(a.sourceIndex < b.sourceIndex && 4) +
(a.sourceIndex > b.sourceIndex && 2) :
1) +
0 :
0;
}
You can use the DOM function compareDocumentPosition which will return different numbers based on the two nodes' relationships:
DOCUMENT_POSITION_DISCONNECTED = 0x01;
DOCUMENT_POSITION_PRECEDING = 0x02;
DOCUMENT_POSITION_FOLLOWING = 0x04;
DOCUMENT_POSITION_CONTAINS = 0x08;
DOCUMENT_POSITION_CONTAINED_BY = 0x10;
Potentially the result could be the sum of more than one of these codes as the answer is a bitmask, but I can't imagine a situation where two of these conditions would be true at the same time. Also note that the "disconnected" result would be returned for instance with nodes that have been created but not added to the document tree yet
Rather difficult, I personally would itterate up each tree till I found a common ansester, then check which parent node(or the actual node if that low) comes first starting with firstChild and working through siblings, something like:
function OrderCheck(node1, node2){
var ar1 = [null, node1];
var ar2 = [null, node2];
for(var i = 1; ar1[i] != null; i++)
ar1[i+1]=ar1[i].parentNode;
for(var i = 1; ar2[i] != null; i++)
ar2[i+1]=ar2[i].parentNode;
ar1.reverse(); ar2.reverse(); // easier to work with.
i = 0;
while( ar1[i] === ar2[i] ){
if(ar1[i] === null)
return 0;
else
i++
}
if(ar1[i] === null)
return 2;
if(ar2[i] === null)
return 1;
if(i != 0){
var n = ar1[i-1].firstChild;
do{
if(n === ar1[i])
return 1;
if(n === ar2[i])
return 2;
}while(n = n.nextSibling);
}
return -1;// Shouldn't happen.
}
var order = OrderCheck(document.body, document.body.previousSibling);
if( order == 1){
// element 1 first
}else if(order == 2){
// element 2 first
}else{
// there was an error.
}
I did just edit this code in an attempt to fix two possible problems, I haven't tested this new edit however, so if something breaks I shall have to try again. (Edited again to fix a "doesn't even run" style bug).

Categories

Resources