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
Related
This code is done in HTML javascript.
The following functions (placero() and runro()) are called in that order. placero() seems to initialize the xs and ys of the object list correctly, but by the time the first line of runro() is called, all of the xs and ys have become NaN.
The goal of the code was to make a program that creates rooms and connects them with corridors. Previous steps have inititalized the rooms and corridor layout, but the job of placero() is to place each room somewhere random on the map.
the code is as follows:
runm does all the initial setting code(such as the room member initialization) and does all the other work before placero(). I have been clicking the buttons in the intended order(sequentially), so that shouldnt be the problem.
var roomes = new Array(0);
function randIntBetween(min, max) { // min and max included
return Math.floor(Math.random() * (max - min + 1) + min);
}
//before any function calls, rooms is initialized as follows(well after the input has been entered, in most cases):
roomMax = document.getElementById("inp1").value; //this is the inputted number of rooms being made
for (var k = 0; k < roomMax; k++) {
var obj = {
ind: k,
x: -1,
y: -1,
neighb: Array(0)
}
roomes.push(obj);
}
//then some work is done, placing the indexes of other rooms in the neighbors array in each room.
//none of the in-between code edits x or y.
function placero() {
for (var kis = 0; kis < roomes.length; kis++) {
var x = randIntBetween(5, mapX - 5); //get a random x and y for room position
var y = randIntBetween(5, 5);
roomes[kis].x = x;
roomes[kis].y = y;
}
console.log(roomes); //prints a correct array
}
function runro() {
console.log(roomes); //prints an incorrect array
var iterCount = 2;
//this code aims to place rooms closer to their neighbors, by averaging a rooms position with that of its neighbors and moving it half the way in that direction.
for (var ki = 0; ki < iterCount; ki++) { //for each iteration in which the rooms are moved,
for (var kt = 0; kt < roomes.length; kt++) { //for each room
var coun = NeighbCount(roomes[kt]); //get number of neighbors(will be used for averageing)
console.log(coun);
var sumx = 0;
var sumy = 0;
for (var km = 0; km < coun; km++) { //for each neighbor,
sumx = sumx + roomes[roomes[kt].neighb[km]].x; //add its position to the sum position
sumy = sumy + roomes[roomes[kt].neighb[km]].y;
}
sumx = sumx / coun; //then divide by number of neighbors to get new position
sumy = sumy / coun;
console.log(sumx + " " + roomes[kt].x); //troubleshooting
console.log(sumy + " " + roomes[kt].y);
roomes[kt].x = sumx / 2 + roomes[kt].x / 2; //setting new positions
roomes[kt].y = sumy / 2 + roomes[kt].y / 2;
}
}
}
<div>
<input type="number" id="inp1" name="inp1"><br>
</div>
<button onclick="runm()">Make room map</button>
<button onclick="placero()">place rooms</button>
<button onclick="runro()">Make rooms</button>
You're probably getting the error because roomMax is of string type and not number type. To solve this, make the following modifications to your code:
roomMax = parseInt(document.getElementById("inp1").value);
The value from an input will always be a string. The code above changes the type.
Look through your code to see if you have any similar mistakes.
I'm not much familiar with javascript, but I faced a need to send and receive big static 2D integer arrays (where values are > 255) as base64 strings (this is essential). At the moment I've came up with this straightforward and inefficient solution converting them element-wise and manually constructing strings, which, as far as I understand, should involve a lot of copying of the data and turns to be very slow.
Can it be done in a more efficient way, if possible without usage of some big side libraries like Node.js, etc?
//----------- serializing/deserializing procedures
//encoding int contours array to be sent as base64 string
function getBase64IntArray(arr) {
var width = arr.length;
//This works given the inner arrays length never changes.
var height = arr[0].length;
//string that would contain data
var str = width.toString()+","+height.toString()+",";
for(var x = 0; x < height; x++) {
for(var y = 0; y < width; y++) {
str = str + arr[x][y].toString() + ",";
}
}
var str64 = btoa(str);
return str64;
}//getBase64IntArray
//deconding this string back to array
function getIntArrayfromBase64(str64) {
var str = atob(str64);
//first occurence of ","
var width_str = str.substr(0,str.indexOf(','));
str = str.substr(str.indexOf(',')+1); // cut the beginning
//again first occurence of ","
var height_str = str.substr(0,str.indexOf(','));
str = str.substr(str.indexOf(',')+1); // cut the beginning
var width = parseInt(width_str);
var height = parseInt(height_str);
//declare new array and fill it
var arr = new Array(height);
var curr_str = "";
for(var x = 0; x < height; x++) {
arr[x] = new Array(width);
for(var y = 0; y < width; y++) {
//first occurence of ","
curr_str = str.substr(0,str.indexOf(','));
// cut the beginning
str = str.substr(str.indexOf(',')+1);
arr[x][y]=parseInt(curr_str);
}
}
return arr;
}// getIntArrayfromBase64
Sending/receiving works:
//----------- example usage
function send(){
//encoding to base64
var arr = [
[1, 2],
[3, 4]
];
var base64 = getBase64IntArray(arr);
webSocket.send(base64);
}
webSocket.onmessage = function(event){
//reading array as base64 string
var arr = getIntArrayfromBase64(event.data);
var width = arr.length;
var height = arr[0].length;
writeResponse("Received "+width+" "+height+" "+arr[0][0]+arr[1][1]);
};
How about going through JSON? JSON will add minimal overhead to the wire format, but the serialization/deserialization will be fast, because it's implemented natively.
function getBase64IntArray(arr) {
return btoa(JSON.stringify(arr))
}
function getIntArrayfromBase64(str64) {
return JSON.parse(atob(str64))
}
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.
I have a string of the following structure:
positions = '15,-2,-3,15'
Which describes points, in this case A(15, -2), B(-3, 15).
Q How would you extract the data from a string like this?
It would be better to get the result as an array of somekind of struct (e.g., point[i].x, point[i].y), but a multidimensional array is also suitable (e.g. point[i][0], point[i][1]).
If you use split, it will turn the values into strings, so you would need to use parseInt() or parseFloat() to convert them back to numbers.
If you just want to get to the numbers quickly without converting them into an object, you can use the power of JSON.parse
var positions = '15,-2,-3,15';
var arrPositions = JSON.parse("[" + positions + "]");
A([arrPositions[0], arrPositions[1]);
B(arrPositions[2], arrPositions[3]);
Something like this would work, you split the string into tokens using the commas as deliminators, and then loop through that array creating some Point object with x and y.
var data = positions.split(',');
var points = [];
for(var i = 0; i < data.length - 1; i++) {
var x = data[i];
var y = data[++i];
points.push(new Point(x,y));
}
I would probably do:
positions = '15,-2,-3,15';
Arr = [];
pos = positions.split(',');
i = 0;
while( pos.length ){
Arr[i++] = pos.splice( 0, 2 );
}
Just for kicks:
(function f (e, s, p, r) {
r = e.exec(s);
return r ? [p(r[1], r[2])].concat(f(e, s, p)) : [];
}(/(-?\d+),(-?\d+)/g, '15,-2,-3,15',
function (x, y) { return { x: x, y: y }; }));
A simple question..
var x = document.getElementById('xNum');
var y = document.getElementById('xNum');
var result = x * y;
document.write(result);
and
<div id="xNum">20</div>
<div id="yNum">50</div>
It displays 20 and 50. why not calculating 20 * 50? Why does it get as a integer or how can I get numbers in an div?
Thanx!
I don't get any result with that:
var x = document.getElementById('xNum').innerHTML;
var y = document.getElementById('xNum').innerHTML;
var result = parseInt(x) * parseInt(y);
document.write(result);
Use parseInt and process it on their HTML,
var result = parseInt(x.innerHTML) * parseInt(y.innerHTML)
If you don't need to support browsers priot to IE9, you should use textContent instead of innerHTML.
If your numbers might be floats you should check out parseFloat instead
If you need to be able to handle numbers like 012 you should specify the radix parameter as they might be interpreted the wrong way by parseInt.
In this case you should use parseInt(x.innerHTML,10)
it should be
var x = document.getElementById('xNum').innerHTML;
var y = document.getElementById('yNum').innerHTML;
var result = x * y;
document.write(result);
Parse them into integers:
var x = document.getElementById('xNum');
var y = document.getElementById('yNum');
var result = parseInt(x.innerHTML, 10) * parseInt(y.innerHTML, 10);
The value you are getting is a string, so in order to use it as a number you should cast it to the integer (or float):
var x = +document.getElementById('xNum').innerHTML;
var y = +document.getElementById('xNum').innerHTML;
var result = x * y;
I used unary + operator, there are another methods like parseInt, Number constructor, etc.
By now the possible ways would have been exhausted, but here's an example with textContent:
var x = document.getElementById('xNum'),
y = document.getElementById('yNum'),
toIntNum = function(element) {
return parseInt(element.textContent || element.innerText || 0, 10);
},
result;
result = toIntNum(x) * toIntNum(y);
Demo
Js:
var x = document.getByElementId('xNum').innerHTML;
var y = document.getByElementId('xNum').innerHTML;
var result = parseInt(x) * parseInt(y);
document.write(result);
you must cast as int so calculation done. By default the value consider as string .
var x = document.getByElementId('xNum');
var y = document.getByElementId('xNum');
var result = parseInt(x) * parseInt(y); //use parseInt or parseDouble
document.write(result);
and
<div id="xNum">20</div>
<div id="yNum">50</div>
it give 1000
You have to use parseInt() function in javascript for parsing a string to return an integer.
Your code should be like this :
var x = document.getElementById('xNum');
var y = document.getElementById('yNum');
var result = parseInt(x.innerHTML) * parseInt(y.innerHTML);
document.write(result);