Javascript - generating random pairs of numbers if pair doesn't already exist - javascript

Edit: If you read Matt Bryant's answer, you'll see that it should work but he uses indexOf() method and that method doesn't work with I.E 8 or later and I need it to work on I.E 8. I tried doing this as a work around to the indexOf() method but it's not working.
var tester = -1;
for (var test=0; test<xposition.length; test++) {
if (x == xposition[0]) {
tseter = x;
}
}
Any idea why it doesn't work?
Original question:
So I want to generate random pairs of numbers but only if the pairs of number didn't already be generated. Here is what I tried, hopefully if you read what I tried, you will understand what it is exactly which I need.
function randomPairs() {
var xposition = []; //array which holds all x coordinates
var yposition = []; //array which holds all y coordinates
for (var i=0; i<5; i++) { //do everything below 5 times (generate 5 pairs)
var x = getRandom(1,7); //generate new x point
var y = getRandom(2,7); //generate new y point
if ( jQuery.inArray(x, xposition) ) { //if newly generated x point is already in the xposition array (if it was already previously generated
var location = xposition.indexOf(x) //find the index of the existing x
if (y == yposition[location]) { //if the newly generated y points equals the same y point in the same location as x, except in the yposition array
while ( y == yposition[location]) {
y = getRandom(2, 7); //change y
}
}
}
}
xposition.push(x); //put x into the array
yposition.push(y); //put y into the array
}
So, any idea why it isn't working? Am I using the jQuery.inArray() and the .indexOf() method properly?
Oh, and getRandom is
function getRandom(min, max) {
return min + Math.floor(Math.random() * (max - min + 1));
}
basically, it generates a number between the min and max.
Also, when I tried to do
alert(xposition);
alert(yposition);
it is blank.

The issue is that you are adding x and y to the array outside of the loop. A fix for this (plus a removal of the unneeded jQuery) is:
function randomPairs() {
var xposition = []; //array which holds all x coordinates
var yposition = []; //array which holds all y coordinates
for (var i=0; i<5; i++) { //do everything below 5 times (generate 5 pairs)
var x = getRandom(1,7); //generate new x point
var y = getRandom(2,7); //generate new y point
var location = xposition.indexOf(x);
if (location > -1) { //if newly generated x point is already in the xposition array (if it was already previously generated
if (y == yposition[location]) { //if the newly generated y points equals the same y point in the same location as x, except in the yposition array
while ( y == yposition[location]) {
y = getRandom(2, 7); //change y
}
}
}
xposition.push(x); //put x into the array
yposition.push(y); //put y into the array
}
}
Note that you should probably return something from this function.
If you have to support old browsers, replace the line
var location = xposition.indexOf(x);
with
var location = jQuery.inArray(x, xposition);

One of the main issue with this approach is that you have to think of cases when there are multiple unique pairs with the same x or y value.
x = [1, 1, 1], y = [1, 2, 3]
Note that Array.indexOf only returns the first index when the given element can be found in the array. So you would have to recursively run it beginning from the index you found the match from.
A simple approach of generating a unique pair of integers can be done without jquery:
http://jsfiddle.net/WaFqv/
I'm assuming the order does matter, so the x = 4, y = 3 & x = 3, y = 4 would be considered as two unique pairs.

Related

Calculating sine values in javascript using for loop, but it keeps crashing. Why?

So I'm trying to calculate values of the function sin(x) by inputting a domain parameter and how many steps to calculate the y values for each respective x value. I know the for loop is the problem because when I comment it out, the page loads fine. However, if the loop is active, then the page crashes.
I thought, "oh, maybe it's because I am looping numbers that are irrational such as PI". Well, I changed the domain to [0, 2] so that the numbers are more "nice", but I still get the same issue.
I tried looking up possible reasons why this is happening, and it seems to be because of some sort of recursion happening somewhere. I don't know where. The code looks right as far as I can tell. Is it possibly be because I don't have enough memory or something?
By the way, I am doing this because I am making a graphing program using HTML5 canvas just for fun and practice.
//domain is the closed interval you want the function to be calculated on [a,b]
//numSteps is the accuracy of your graph
function sinGraph(domain, numSteps) {
//prepare x and y value arrays
var yVal = [];
var xVal = [];
//check if the function parameters are acceptable
if (domain[0] == domain[1] || numSteps <= 0) {
alert("Invalid inputs. Domain must be in format [a, b] where a does not equal b. Number of steps must be greater than zero.");
} else {
//define interval length
var intLength = Math.abs(domain[1] - domain[0]);
//find the number of steps
var stepSize = intLength / numSteps;
//calculate y values based on x values
//push x and y values into arrays based on numSteps
for (var i = domain[0]; i<=domain[1]; i+stepSize) {
var xTemp = i;
var yTemp = Math.sin(i);
xVal.push(xTemp);
yVal.push(yTemp);
}
//return x and y value arrays
return {
xVal: xVal,
yVal: yVal
};
}
}
//test
var graph = sinGraph([0, Math.PI], 20);
alert(graph.yVal);
Just a minor typo in the incremental portion of the for loop:
//calculate y values based on x values
//push x and y values into arrays based on numSteps
for (var i = domain[0]; i<=domain[1]; i += stepSize) {
var xTemp = i;
var yTemp = Math.sin(i);
xVal.push(xTemp);
yVal.push(yTemp);
}

2D dynamic javascript matrix for coordinates object

I'm trying to make a 2D matrix dynamic system which identifies whether there is an "object" at X,Y coordinates (true), or not (false).
Simplified example code:
var coords = [[]]; // Matrix is over 10,000 x 10,000
var objectX = 76;
var objectY = 54;
coords[objectX][objectY] = true;
//Check to see if there is an object # coordinates
if(coords[100][65] == false || coords[100][65] === undefined)
{
//There is no object # 100 x 65
}
else
{
//Object detected # 100 x 65
}
But it seems I can't do it this way, since I think I have to start from [0][0], [0][1], [0][2], ... , ect; or something..
Also, matrix is too large to define via putting it in a loop. I can't have it loading for hours.
I won't mind keeping an array segment 'undefined', as I treat it as false in my code.
How can I accomplish this?
You need to make sure the first dimension array exists before you address the second dimension:
if (coords[objectX] === undefined) coords[objectX] = [];
coords[objectX][objectY] = true;
If upfront you know you actually need an element for each X,Y position (which will consume more memory), then initialise the matrix first with a loop:
for (var objectX=0; objectX <= maxX; objectX++) {
coords[objectX] = [];
for (var objectY=0; objectY <= maxY; objectY++) {
coords[objectX][objectY] = false;
}
}
Depending on your needs, you might get better memory usage and performance if you would use a different structure:
var coords = [];
coords[objectX * (maxX + 1) + objectY] = true;
Or if you do not know the range of X nor Y:
coords = {}; // object whose properties will be X,Y strings:
coords[objectX + ',' + objectY] = true;

Applying math to values in an array

I have an array:
var myarray = ["5,35.0", "15,45.0", "25,45.0", "35,50.0", "45,60.0", "55,65.0", "65,60.0", "75,60.0", "85,70.0", "95,80.0"]
the values correspond to x,y points on a graph.
I need to apply math to each y value to change the y-axis scale. To keep it simple, let's say I need to multiply each y value by 2.
How would I go about this?
Use map to loop over the array, converting the string to a pair of numbers, performing the addition ensuring that the decimal place is kept intact.
var out = myarray.map(function (el) {
var xy = el.split(',').map(Number);
xy[1] = (xy[1] * 2).toFixed(1);
return xy.join(',');
});
Fiddle
You need to loop through every element and split them via ',' and then do the MATH over it and save it back.
Say,
for(var i=0;i<myarray.length;i++){
var temp = (parseFloat(myarray[i].split(',')[1])).toFixed(2);
temp = temp * 2;
myarray[i] = myarray[i].split(',')[0] + "," + temp;
}
Roughly,
var myarray = ["5,35.0", "15,45.0", "25,45.0", "35,50.0", "45,60.0", "55,65.0", "65,60.0", "75,60.0", "85,70.0", "95,80.0"];
var y = 0;
var x = 0;
for(var i in myarray) {
y = parseFloat(myarray[i].split(",")[1]);
x = parseFloat(myarray[i].split(",")[0]);
y = y * 2; // or your operation
myarray[i] = x + "," + y;
}
console.log(myarray);
HTH

Access elements of a list using JQuery

I'm completely new to JQuery and I hope to get some help from SO folks.
This snippet basically generated a random numbers and filled a list along with index values
i.e. [0 10],[1 12],[2 30]... so on
function getRandomData() {
if (data.length > 0)
data = data.slice(1);
// do a random walk
while (data.length < totalPoints) {
var prev = data.length > 0 ? data[data.length - 1] : 50;
var y = prev + Math.random() * 10 - 5;
if (y < 0)
y = 0;
if (y > 100)
y = 100;
data.push(y);
}
// zip the generated y values with the x values
var res = [];
for (var i = 0; i < data.length; ++i)
res.push([i, data[i]])
return res;
}
Can any one out there help me out with the syntax to retrieve the elements inside data
which is in turn present in the res collection.
i.e. i want to know the random number generated each time the function getRandomData
is called
I hope i made it clear
Regards
Something like that?
// Save the return value of the function in a variable
var arr = getRandomData();
// Print data to the console
console.log(arr)
// Print the first dataset
console.log(arr[0]) // [0, 29]
// Print only the number of the first set
console.log(arr[0][1])
Do you mean something like this?
var res = [
[0, 10],
[1, 12],
[2, 30]
];
var x = res[0][1]; // returns 10
var y = res[1][1]; // returns 12
var z = res[2][1]; // returns 30
You can access any sub-arrays using this syntax:
array[first level index][second level index][...nth level index];
The data var appears to come from outside the function scope so you could just do
console.log(data)
Though I guess you're maybe asking for the syntax as given by #MildlyInteresting ?

Check an array of x y grid co-ordinates for duplicates and remove

I have a grid based game 8 squares by 8 squares giving 64 pieces in total, these pieces are stored in an array. I'm having a problem where certain grid squares are being populated twice so I need to check the array for duplicate co-ordinates.
Below code gives the x, y grid co-ordinates of each piece - testX and testY, I'm not sure how I would go about running through this array to remove duplicates. If there are duplicates pieces I need to keep the first encountered and remove any subsequent duplicates. I'm using jQuery if that helps.
function checkGrid() {
var x;
for (x = 0; x < grid.length; x++) {
var testY= grid[x].getY();
var testX = grid[x].getX();
}
}
You could consider using an object instead of an array:
var grid = {};
function setGridValue(x,y, value){
var key = x + '-' + y;
grid[key] = value;
}
function getGridValue(x,y){
var key = x + '-' + y;
return grid[key];
}
Something like this. Then if you change the value of a grid location, you don't need to check for duplicates.
EDIT.
Since you can't change to object, you should find an existing item when you insert them. You didn't post the code where you add items to the grid, but can you do something like this:
function setItem(x, y, value){
var item;
// check for existing item in array
for(var i = 0; i < grid.length; i++){
if(grid[i].getX() === x && grid[i].getY() === y){
item = grid[i];
break;
}
}
// if no existing item, create new one
if(!item){
item = new GridItem(x,y,value); // dont know what is in the grid...
grid.push(item);
} else {
// update existing item here...
}
}

Categories