Changing one variable changes all others defined the same way - javascript

I have a JavaScript code which has 4 3-dimensional arrays that are each of 500x500x220 dimension (all 220 values in the last dimension are rarely all used). Because of this large dimension, it's much faster to define one array like this and then define the four arrays from that one. The problem is that then, when I change a value in one array, it changes in the others also. Here's my code:
<script type="text/javascript">
var content = new Array();
var signs = new Array();
var sens = new Array();
var props = new Array();
var ini = new Array();
for(i = 0; i < 500; i++){
ini[i] = new Array();
for(j = 0; j < 500; j++){
ini[i][j] = new Array();
}
}
content = ini;
signs = ini;
sens = ini;
props = ini;
function f(){
alert(signs[3][3][2]); //Returns undefined
content[3][3][2] = 2;
alert(signs[3][3][2]); //Returns 2
}
f();
</script>
Notice that the f() function is only supposed to change the content array but it also changes the signs array. Why does it do that and how do I get around it?
In case it makes a difference, I'm using HTA.

With the help of this post about copying nested arrays.
Your code:
content = ini;
signs = ini;
sens = ini;
props = ini;
makes the arrays to point to ini. That's why any reference to content[0], for instance, is a reference to signs[0] and ini[0] as well.
Use:
function copy(arr){
var new_arr = arr.slice(0);
for(var i = new_arr.length; i--;)
if(new_arr[i] instanceof Array)
new_arr[i] = copy(new_arr[i]);
return new_arr;
}
to copy the arrays:
content = copy(ini);
signs = copy(ini);
sens = copy(ini);
props = copy(ini);

Related

Add an existing var to a new object in JavaScript and loop through them

I find numerous guides on how to add variables to existing objects, but nowhere how to add an "existing" variable to an existing object.
I have a whole list with variables already defined in my script. e.g.: a, b, c, d.
and they all have their own values.
Now I want to call a function on all these variables and then show the variable-names and outcome in console.
Therefor I want to create an object out of them to loop through. How do I do this?
This is my workflow:
Values are created in various places in the script:
a = 1.333;
b = 1.64252345;
c = 2.980988;
I create the object and try to add the already existing variables (this is where I fail):
var abc = {};
abc.a;
abc.b;
abc.c;
I want to loop through the object, flooring all numbers, and printing the variable-name with the returned number:
var i;
for (i = 0; i < abc.length; ++i) {
var variablename = Object.keys(abc[i]);
var flooredvalue = floor(abc[i]);
var abc[i] = flooredvalue; // Save the floored value back to the variable.
console.log(variablename+": "+flooredvalue);
}
My desired output in console.log:
a = 1
b = 1
c = 2
Looping through the array of object keys will be a good idea.
a = 1.333;
b = 1.64252345;
c = 2.980988;
var abc = {};
abc.a = a;
abc.b = b;
abc.c = c;
var i;
var keys = Object.keys(abc);
console.log(abc['a'])
for (i = 0; i < keys.length; i++) {
var key = keys[i];
var flooredvalue = Math.floor( abc[key] );
abc[key] = flooredvalue;
window[key] = flooredvalue; //global variable change.
}
console.log(a);
console.log(b);
console.log(c);

javascript - create new (global) objects with names from array

i am trying to create new Objects with names out of an array.
Without an array i would do:
var object_bruno = new Object();
var object_carlos = new Object();
var object_luci = new Object();
so i will end up with 3 new Objects. But why wont we do that with an loop, which makes it more easy to adde some more Objects later. So i ttried:
// an array full of object names
var obj_arr = [ "object_bruno", "object_carlos", "object_luci"];
// Method one:
for (x in obj_arr) {
alert(obj_arr[x]); // right names shown
var obj_arr[x] = new Object(); //syntax error, dosent work??
};
// Method two:
obj_arr.forEach(function(func_name) {
alert(func_name); // right names
var func_name = new Object(); // no objects are created ???
});
basicly i would prefer to use Method two. i like it because i can fill them late the same way? hopefuly? Any ideas what wents wrong?
You can just loop over the array and assign a new Object to each of the items , like this:
for (var i = 0, l = obj_arr.length; i < l; i++) {
obj_arr[i] = {};
}
UPDATE
You can also do it in this way by applying properties to the global object, for example window:
var people = [ "object_bruno", "object_carlos", "object_luci"];
for (var i = 0, l = people.length; i < l; i++) {
global[people[i]] = {};
}
Using this solution makes the objects global, so you can use them like object_bruno.
Another improvement can be the usage of computed propertiey names of ECMAScript 2015:
var people = [ "bruno", "carlos", "luci"], prefix = 'object_';
for (var i = 0, l = people.length; i < l; i++) {
global[prefix + people[i]] = {};
}
This allows to have more meaningful array.
Note, the global can be the window object in browsers or global object in NodeJS, or perhaps something else in other environments.
Because you are creating a new variable by declaring
obj_arr.forEach(function(func_name) {
alert(func_name); // right names
var func_name = new Object(); // no objects are created ???
});
try this
obj_arr.forEach(function(func_name) {
alert(func_name); // right names
func_name = new Object(); // no objects are created ???
});
var obj_arr = [ "object_bruno", "object_carlos", "object_luci"];
obj_arr.forEach(function(func_name, index, arr) {
arr[index] = {};
});

Most efficient way to parse a complex string in Javascript

I'm having trouble parsing this string.
newParams=[ "3","2","img1x:51","img1y:111","img1h:209","img1w:330","img1Px:231","img1Py:291","img1Dx:44","img1Dy:104","img2x:51","img2y:331","img2h:100","img2w:329","img2Px:274","img2Py:408","img2Dx:44","img2Dy:324","txt1x:399","txt1y:119","txt1h:103","txt1w:303","txtBox1x:391","txtBox1y:111","txtBox1h:119","txtBox1w:319","txt1Px:679","txt1Py:199","txt1Dx:392","txt1Dy:112","txt2x:399","txt2y:249","txt2h:103","txt2w:303","txtBox2x:391","txtBox2y:241","txtBox2h:119","txtBox2w:319","txt2Px:679","txt2Py:329","txt2Dx:392","txt2Dy:242","txt3x:399","txt3y:379","txt3h:44","txt3w:304","txtBox3x:391","txtBox3y:371","txtBox3h:60","txtBox3w:320","txt3Px:680","txt3Py:409","txt3Dx:392","txt3Dy:372"];
The string contains the height, width, x and y coordinates of both text objects and image objects that I need to position and resize in the DOM.
The first 2 values in the array are the number of textfields, and the number of images (which i was going to use in loops as the max number of iterations).
I need to parse the number values, and push them in these individual arrays.
var textXcoords = new Array();
var textYcoords = new Array();
var textHeight = new Array();
var textWidth = new Array();
var txtBoxXcoords = new Array();
var txtBoxYcoords = new Array();
var txtBoxHeight = new Array();
var txtBoxWidth = new Array();
var textPullXcoords = new Array();
var textPullYcoords = new Array();
var textDragXcoords = new Array();
var textDragYcoords = new Array();
var imgXcoords = new Array();
var imgYcoords = new Array();
var imgHeight = new Array();
var imgWidth = new Array();
var imgPullXcoords = new Array();
var imgPullYcoords = new Array();
var imgDragXcoords = new Array();
var imgDragYcoords = new Array();
For instance in "img1x:51" (image 1, Y coord), the number 51 would be pushed into the imgXcoords array at position 0.
and in "img2y:111" (image 2, Y coord), the number 111 would be pushed into the imgYcoords array at position 1.
and in "txt2w:303" (textfield 2, width), the number 303 would be pushed into the txtBoxWidth array at position 1.
If someone can show me just how to push the img(i)x and img(i)y values into their arrays (imgXcoords and imgYcoords) using a loop, I can figure out the rest from there.
I just don't know the most efficient way to search what I am looking for in the string and push it into the proper array.
I tried this for the x coordinates of the images, but my start and end positions are way off.
var iX1 = newParams.indexOf("img"+(1)+"x");
var iX2 = (iX1 + 7);
var res = newParams.substr(iX2,(iX2+2));
if I send "res" to the console.log, I get:
1","img1y:111","im as a result.
When I put that into a loop, and sub "1" with var i=0, it gets even more wacky.
Here is a jfiddle of my attempt: http://jsfiddle.net/S9RGH/
split is your friend. See if what I did here helps: jsfiddle
You can use split to segment the string into individual name/value pairs and put them in an array for easy access.
While this isn't what I could call the most efficient code, it is I believe the most readable solution...
I'd only work about optimizing it if it turned out to be a major performance hit. To optimize it, I'd go through the data object and turn it into a cleaner structure to parse.
var data = [
"3", "2", "img1x:51", "img1y:111", "img1h:209", "img1w:330", "img1Px:231", "img1Py:291", "img1Dx:44", "img1Dy:104", "img2x:51", "img2y:331", "img2h:100", "img2w:329", "img2Px:274", "img2Py:408", "img2Dx:44", "img2Dy:324", "txt1x:399", "txt1y:119", "txt1h:103", "txt1w:303", "txtBox1x:391", "txtBox1y:111", "txtBox1h:119", "txtBox1w:319", "txt1Px:679", "txt1Py:199", "txt1Dx:392", "txt1Dy:112", "txt2x:399", "txt2y:249", "txt2h:103", "txt2w:303", "txtBox2x:391", "txtBox2y:241", "txtBox2h:119", "txtBox2w:319", "txt2Px:679", "txt2Py:329", "txt2Dx:392", "txt2Dy:242", "txt3x:399", "txt3y:379", "txt3h:44", "txt3w:304", "txtBox3x:391", "txtBox3y:371", "txtBox3h:60", "txtBox3w:320", "txt3Px:680", "txt3Py:409", "txt3Dx:392", "txt3Dy:372"
];
var imgXcoords = [];
var imgYcoords = [];
var imgHeight = [];
var imgWidth = [];
var bucket;
// Trimmed for simplicty
// The names of the fields we are looking for
var fields = ["img?x", "img?y", "img?h", "img?w"];
// The arrays they go in.
// Keep these in the same order as the 'fields' above.
var dests = [imgXcoords,
imgYcoords,
imgHeight,
imgWidth
];
// Since the counts starts at '1'
var imageCount = +data[1] + 1;
// Go through the images
for (var i = 0; i < imageCount; i++) {
// And each field we are looking for
for (var ii = 0; ii < fields.length; ii++) {
// Make the name of the thing we are looking for.
var wantedKey = fields[ii];
wantedKey = wantedKey.replace("?", i);
// Then walk through the array. FUGLY
// I know, but simple.
for (var j = 0; j < data.length; j++) {
// Split the value up.
var arr = data[j].split(':');
if (arr) {
var currentKey = arr[0];
// Force to a number
var value = +arr[1];
console.log([currentKey, wantedKey]);
// we found what we want? Great!
if (currentKey === wantedKey) {
bucket = dests[ii];
bucket.push(value);
continue;
}
}
}
}
}
debugger;

Group array items based on variable javascript

I have an array that is created dynamic from an xml document looking something like this:
myArray[0] = [1,The Melting Pot,A]
myArray[1] = [5,Mama's MexicanKitchen,C]
myArray[2] = [6,Wingdome,D]
myArray[3] = [7,Piroshky Piroshky,D]
myArray[4] = [4,Crab Pot,F]
myArray[5] = [2,Ipanema Grill,G]
myArray[6] = [0,Pan Africa Market,Z]
This array is created within a for loop and could contain whatever based on the xml document
What I need to accomplish is grouping the items from this array based on the letters so that all array objects that have the letter A in them get stored in another array as this
other['A'] = ['item 1', 'item 2', 'item 3'];
other['B'] = ['item 4', 'item 5'];
other['C'] = ['item 6'];
To clarify I need to sort out items based on variables from within the array, in this case the letters so that all array objects containing the letter A goes under the new array by letter
Thanks for any help!
You shouldn't use arrays with non-integer indexes. Your other variable should be a plain object rather than an array. (It does work with arrays, but it's not the best option.)
// assume myArray is already declared and populated as per the question
var other = {},
letter,
i;
for (i=0; i < myArray.length; i++) {
letter = myArray[i][2];
// if other doesn't already have a property for the current letter
// create it and assign it to a new empty array
if (!(letter in other))
other[letter] = [];
other[letter].push(myArray[i]);
}
Given an item in myArray [1,"The Melting Pot","A"], your example doesn't make it clear whether you want to store that whole thing in other or just the string field in the second array position - your example output only has strings but they don't match your strings in myArray. My code originally stored just the string part by saying other[letter].push(myArray[i][1]);, but some anonymous person has edited my post to change it to other[letter].push(myArray[i]); which stores all of [1,"The Melting Pot","A"]. Up to you to figure out what you want to do there, I've given you the basic code you need.
Try groupBy function offered by http://underscorejs.org/#groupBy
_.groupBy([1.3, 2.1, 2.4], function(num){ return Math.floor(num); });
Result => {1: [1.3], 2: [2.1, 2.4]}
You have to create an empty JavaScript object and assign an array to it for each letter.
var object = {};
for ( var x = 0; x < myArray.length; x++ )
{
var letter = myArray[x][2];
// create array for this letter if it doesn't exist
if ( ! object[letter] )
{
object[letter] = [];
}
object[ myArray[x][2] ].push[ myArray[x] ];
}
Demo fiddle here.
This code will work for your example.
var other = Object.create(null), // you can safely use in opeator.
letter,
item,
max,
i;
for (i = 0, max = myArray.length; i < max; i += 1) {
item = myArray[i];
letter = myArray[2];
// If the letter does not exist in the other dict,
// create its items list
other[letter] = other[letter] || [];
other.push(item);
}
Good ol' ES5 Array Extras are great.
var other = {};
myArray.forEach(function(n, i, ary){
other[n[2]] = n.slice(0,2);
});
Try -
var myArray = new Array();
myArray[0] = [1,"The Melting Pot,A,3,Sake House","B"];
myArray[1] = [5,"Mama's MexicanKitchen","C"];
myArray[2] = [6,"Wingdome","D"];
myArray[3] = [7,"Piroshky Piroshky","D"];
myArray[4] = [4,"Crab Pot","F"];
myArray[5] = [2,"Ipanema Grill","G"];
myArray[6] = [0,"Pan Africa Market","Z"];
var map = new Object();
for(i =0 ; i < myArray.length; i++){
var key = myArray[i][2];
if(!map[key]){
var array = new Array();
map[key] = array;
}
map[key].push(myArray[i]);
}

What's wrong with this javascript? Array not defined

What's wrong with this code?
var divarray = document.getElementById("yui-main").getElementsByTagName("div");
var articleHTML = array();
var absHTML;
var keyHTML;
var bodyHTML = array();
var i = 0;
for ( var j in divarray) {
if(divarray[i].className == "articleBody"){
alert("found");
articleHTML = divarray[i];
break;
}
bodyHTML[i] = '';
if(articleHTML[i].className == "issueMiniFeature"){continue;}
if(articleHTML[i].className == "abstract"){absHTML = articleHTML[i]; continue;}
if(articleHTML[i].className == "journalKeywords"){keyHTML = articleHTML[i]; continue;}
bodyHTML[i] = articleHTML[i];
i++;
}
This is the error I am getting:
ReferenceError: array is not defined
I am using Google Chrome if it helps any.
It's not php - you should use
var variable_name = new Array()
or even better
var variable_name = []
That's not how to declare variables as an empty array. You should be using:
var articleHTML = [];
See this previous question for reasoning of using this method instead of new Array()
It's [] in ECMAScript; this isn't PHP. The interpreter is right - array is not defined, which is why you're getting that.
var articleHTML = new Array();
Note! Javascript IS case sensitive you have to use upper-case A in word Array.
var myarr = new array(); //THIS IS WRONG! and will result in error not defined
So these are the correct ways:
var myarr = new Array(); //THIS IS CORRECT (note the "big" A) :)
var myarr = []; //and this is correct too
Instead of
var articleHTML = array();
and
var bodyHTML = array();
do
var articleHTML = [];
and
var bodyHTML = [];
You first need to define
var divarray = new Array();
You also don't need to use var six times, you can do:
var divarray = document.getElementById("yui-main").getElementsByTagName("div"),
articleHTML = [],
absHTML = [],
keyHTML = [],
bodyHTML = [],
i = 0;
Which works just as well as your six vars but looks much nicer.
Also there are a number of compelling reasons not to use new in instantiate an array (besides []; is much shorter than new Array();)

Categories

Resources