why is this javascript array undefined? - javascript

I have the following code, which attempts to generate a 2 dimensional array of random numbers:
var block_size = 32;
var can_width = can.width;
var color_depth = 12;
var passes = can_width / block_size;
var map_store = new Array(passes);
for(i=0;i<passes;i++) {
for(j=0;j<passes;j++) {
map_store[i] = new Array(passes);
color = Math.random() * color_depth;
map_store[i][j] = Math.round(color);
}
}
which seems to work fine if i put console.log statements within the loop, however if I try to access the map_store array outside of the loops. all of it's elements are undefined. why is this?

map_store[i] = new Array(passes); should be above the 2nd for loop. You're clearing your previous j values.
for(i=0;i<passes;i++) {
map_store[i] = new Array(passes); // <--
for(j=0;j<passes;j++) {
color = Math.random() * color_depth;
map_store[i][j] = Math.round(color);
}
}

Related

Javascript: Object method - why do I need parentheses?

I am learning javascript and Ive stumbled upon issue that I do not understand. Could somebody explain to me why in method compareDNA I need to use parentheses while using this.dna and in the previous method it works just fine?
// Returns a random DNA base
const returnRandBase = () => {
const dnaBases = ['A', 'T', 'C', 'G'];
return dnaBases[Math.floor(Math.random() * 4)];
};
// Returns a random single stand of DNA containing 15 bases
const mockUpStrand = () => {
const newStrand = [];
for (let i = 0; i < 15; i++) {
newStrand.push(returnRandBase());
}
return newStrand;
};
function pAequorFactory(specimenNum, dna){
return {
specimenNum,
dna,
mutate(){
let i = Math.floor(Math.random() * 15)
let newGene = returnRandBase()
while (this.dna[i] === newGene){
newGene = returnRandBase()
}
this.dna[i] = newGene
return this.dna
},
compareDNA(object){
let counter = 0
for(let i = 0; i < this.dna().length; i++){
if(this.dna()[i] === object.dna()[i]){
counter++
}
}
let percentage = counter / this.dna().length * 100
return `Specimen number ${this.specimenNum} and specimen number ${object.specimenNum} have ${percentage}% of DNA in common.`
},
}
}
let aligator = pAequorFactory(1, mockUpStrand)
let dog = pAequorFactory(2, mockUpStrand)
console.log(aligator.compareDNA(dog))
console.log(dog.dna().length)
The problem is that the dna that is passed as an argument is a function, so it becomes a method of the returned object, and needs to be called with .dna(). However, this looks like a mistake - actually an array should have been passed:
let aligator = pAequorFactory(1, mockUpStrand())
// ^^
let dog = pAequorFactory(2, mockUpStrand())
// ^^
Then you can access .dna[i] or .dna.length as normal.
If you don't do that, dog.dna() returns a different DNA every time, which doesn't make sense.
using this.dna and in the previous method it works just fine?
Actually, it doesn't. dog.mutate() does return a function with a single integer property. It's supposed to return an array really.

How do i store multiple random values in an array with localstorage

I am trying to store multiple values, so I run a function that generates the values and then I store them with localStorage, however, I can't seem to get the values stored. I added in 1, 2 and that seems to work but the randomly generated values don't. From the image, you can see only 2 numbers have stored.
https://gyazo.com/a7180cac935809ca48c244794df3a6ca
$.getJSON("/products.json", function(product) {
var value = [1, 2];
console.log(value);
localStorage["value"] = JSON.stringify(value);
$.each(product.products, function() {
var sMin = 5;
var sMax = 20;
var randomSelect = sMin + Math.floor(Math.random() * sMax);
var t = randomSelect.toString();
value.push(t);
});
});
var test = JSON.parse(localStorage["value"]);
console.log(test);
I think you can use this method localStorage.getItem("key").

How to reduce number of computations during d3.js transition?

So right now, I'm trying to implement a search bar function into my d3.js plot. Right now it doesn't do anything, but that's not the issue at the moment. The problem is that when I type/delete something from the bar, there's visible lag/choppiness in the characters appearing/disappearing. I believe the issue is stemming from my plot. I have 140+ dots moving around the screen, and their position is being interpolated. So from the beginning to the end of the transition, my code has to compute 140 positions thousands of times over.
I've looked into trying to reduce the cardinality of the d3.interpolateNumber function, but it appears that there isn't a third argument to change the number of terms like in a linspace command. Right now I have an array of 1000 numbers for my function to run through, but I don't know how to pass the array to my other functions.
Below are the pertinent functions for this issue. The commented line in tweenPatch is the original code I had that made my code run, but gave my plot computational issues. Variables arr, curr, and step were my attempt to fix the situation, but I haven't been able to figure out how to pass the array into displayPatch().
function tweenPatch() {
var patch = d3.interpolateNumber(1, 26);
var arr = [];
var curr = 1;
var step = (26 - 1) / (1000 - 1);
for (var i = 0; i < 1000; i++) {
arr.push(curr + (step * i));
}
return arr.forEach(function(d) {
console.log(arr[d]);
displayPatch(arr[d]);
});
//return function(t) { displayPatch(t); };
}
function displayPatch(patch) {
dots.data(interpolateData(patch), function(d) { return d.name; }).call(position).sort(order);
var inter = Math.floor(patch);
var seas = 8;
var patc = 1;
if (inter > 24) {
seas = 9;
patc = inter - 24;
} else {
patc = inter;
}
label.text("Patch " + seas + "." + patc);
}
function interpolateValues(values, number) {
old = Math.floor(number);
upd = Math.ceil(number);
var old_data = values.filter(function(d) {return d.internal == old;});
var new_data = values.filter(function(d) {return d.internal == upd;});
var oobj = old_data[0];
var nobj = new_data[0];
var onum = oobj[Object.keys(oobj)[4]];
var nnum = nobj[Object.keys(nobj)[4]];
var difint = number - old;
var difdis = 0;
var newnum = nnum;
if (nnum > onum) {
difdis = nnum - onum;
newnum = ((difint) * difdis) + onum;
} else if (onum > nnum) {
difdis = onum - nnum;
newnum = onum - ((difint) * difdis);
}
return newnum;
}
I believe switching my SVG to a canvas may help things, but since I have no knowledge of canvas I'd rather leave that as a last resort.

Resulting "undifined" after using splice

Im trying to code a random houses generator in JS for a game of thrones game,
the code looks like that at the moment:
//Houses Array:
var HousesArray = [
'Stark',
'Lanister',
'Greyjoy',
'Barathion',
'Arryn',
'Tyrell',
'Martell',
'Targaryen'
];
//Houses Variables:
var house1 = {}
var house2 = {}
var house3 = {}
//Random House Generator
var RandomIndex = Math.floor(Math.random()*HousesArray.length)
var RandomElement = HousesArray[RandomIndex]
//3 Players Generator:
house1 = RandomElement
console.log(house1)
HousesArray.splice(house1,1)
RandomElement = HousesArray[RandomIndex]
house2 = RandomElement
console.log(house2)
HousesArray.splice(house2,1)
RandomElement = HousesArray[RandomIndex]
house3 = RandomElement
console.log(house3)
What I tryed to do here is to give the house1 variable a random house name from one of the HousesArray Eelements,
echo that to the console log,
then remove the selected element from HousesArray using the splice commend (to ensure that the next selection will not be the same one).
after all that - generate new house name from the elements left in the HousesArray and repeat.
But for some reasos, Every time house1 = "Targaryen" (or house2) the next 2/1 resolts automaticly return "undifined" (I beleive its becuse the "Targaryen" element is the last in the list)
How can i fix that?
Your code is not working because RandomIndex is always the same, if it's 7, it will return undefined because splice modifies the original array by removing the found House,
change RandomIndex to be a function to call everytime so it generates a new index using the new length of the array:
var RandomIndex = () => Math.floor(Math.random() * HousesArray.length)
//Houses Array:
var HousesArray = [
'Stark',
'Lanister',
'Greyjoy',
'Barathion',
'Arryn',
'Tyrell',
'Martell',
'Targaryen'
];
//Houses Variables:
var house1 = {}
var house2 = {}
var house3 = {}
//Random House Generator
var RandomIndex = () => Math.floor(Math.random() * HousesArray.length)
var RandomElement = HousesArray[RandomIndex()]
//3 Players Generator:
house1 = RandomElement
console.log(house1)
HousesArray.splice(HousesArray.indexOf(house1), 1)
RandomElement = HousesArray[RandomIndex()]
house2 = RandomElement
console.log(house2)
HousesArray.splice(HousesArray.indexOf(house2), 1)
RandomElement = HousesArray[RandomIndex()]
house3 = RandomElement
console.log(house3)
Doesn't appear you're using the splice method correctly here, it takes the first 2 arguments as numbers, and the third argument would be an element you want to replace it with if you'd like. Instead I would use a filter here:
let newHouseArray = HousesArray.filter(house => house !== house1)
This kept me stumped for quite a while, I would do something like this instead:
Now if you console.log(houses) you will get 3 random houses from random positions (as stated in the above comment) allowing players 2 and 3 to get houses earlier in position than players 1 and 2
Hope this helps :) seem's like a fun game:
//Houses Array:
var HousesArray = ['Stark', 'Lanister', 'Greyjoy', 'Barathion', 'Arryn', 'Tyrell', 'Martell', 'Targaryen'];
// stores the houses
var houses = [];
// Generates 3 random numbers and allows players 2 and 3 to get the houses early in position than player 1 and 2
var arr = [];
while (arr.length < 3) {
var r = Math.floor(Math.random() * 8);
if(arr.indexOf(r) === -1) arr.push(r);
}
// Pushed the houses to the house array
for (var x = 0; x < arr.length; x++) {
houses.push(HousesArray[arr[x]])
}
console.log(houses);

How to copy an array array of numbers using slice()

I am trying to fill a game board (8 by 8) with random game pieces (images), but not the entire board is filled. Some will be empty. To do so, I am randomly generating x,y coordinates on the board and assigning a random number to it. Since fillBoard is private function in a module, I am copy it over to copyBoard, which is public function.
The idea is to randomly generate an x,y coordinate and put it in an array[x], array[y]. I am having trouble copying the array array though, since not all of them is defined. I was wondering how do you do so?
Here's what I got so far. Its displaying an error because splice() cannot work for an undefined variable.
function fillBoard(){
var x, y;
monsters=[]; //empty array
x = Math.floor(Math.random()*cols);
y = Math.floor(Math.random()*rows);
monsters[x] = []; /* making x variable an array */
monsters[x][y] = Math.floor(Math.random() * numMonsterTypes);
}
function copyBoard() {
var copy = [],
x;
for (x = 0; x < cols; x++) {
if(monsters[x]){
copy[x] = monsters[x].slice(0); //slice(array) -> returns the selected elements in an array
};
};
return copy;
}
It looks like your problem arises from only random array element being initialised.
You can either iterate over all rows AND columns and copy initialise elements only
or
you can store a list/array of initilised elements somewhere else (array element maxRow+1/maxCol+1 ?)
Here's the solution:
function fillBoard(){
var x, y;
monsters=[]; //empty array
x = Math.floor(Math.random()*cols);
y = Math.floor(Math.random()*rows);
monsters[x] = []; /* making x variable an array */
monsters[x][y] = Math.floor(Math.random() * numMonsterTypes);
}
function copyBoard() {
var copy = [],
x;
for (x = 0; x<cols; x++){
copy[x] = [];
if(monsters[x]){
copy[x] = monsters[x].slice(0);;
};
};
return copy;
}

Categories

Resources