javascript pointers array or #define for abbreviation - javascript

I have a multi-dimensional array with different types of variables, like this:
array = [ [[file, name, visible], [ArrayPoint, ArrayOther], ...], [[file2,...], ..] ]
now in my code multiple times I have to call (for example) an Array() of points which is located in myArray [X] [1] [0].
I wanted to know if there was the possibility of creating definitions or pointers to the array position to shorten the code, because often I do not remember the variable positions.
// access the value at the address available in pointer
var *pointArray = &myArray[X][1][0];
// my code
*pointArray.push(pint_x, point_y);
============== VS ==============
myArray[X][1][0].push(pint_x, point_y);
thank you very much!! and good evening.
by Marco.

If you do
var pointArray = myArray[X][1][0];
It will make a copy of the reference to the array at myArray[X][1][0]. Therefore, any subsequent mutations to the elements of pointArray will also change the elements of myArray[X][1][0].
Note that reassigning a new value to pointArray as a whole would not effect myArray[X][1][0], since that would only make pointArray store something else.
Assignments do not copy/clone objects in JavaScript, they only make the variable on the left-hand side reference the same object as what's on the right-hand side.
var outer = [[0,1,2],[3,4,5]];
var inner = outer[1];
inner.push(6);
console.log(JSON.stringify(outer));
inner = [];
console.log(JSON.stringify(outer));

ok, thanks I understand.
my problem was that I created the variable called before filling the main array.
this is because I create the empty array structure, but is filled successively by the program events.
now to solve the problem I create the connection variable after the first event push to the primary array.
thank you very much for your availability.

Related

how to update a value in array scoped variable?

I have a scoped variable that stores an archive:
viewScope.MY_SCOPE = new Array();
viewScope.MY_SCOPE.push(["id0", 0, true]);
viewScope.MY_SCOPE.push(["id1", 1, false]);
viewScope.MY_SCOPE.push(["id2", 3, true]);
now I want to update one of item.
viewScope.MY_SCOPE[1][2] = "true";
and this fails with the error:
Error while executing JavaScript action expression put(int index,FBSValue value) not supported in JavaWrapperObject.
How do I update a specific item in the array?
When adding the SSJS array object to the scope, it is converted to a java.util.Vector. Hence, if you want to set the value, you should use
viewScope.MY_SCOPE[1].set(2,"true");
instead of viewScope.MY_SCOPE[1][2] = "true";.
I think the problem is that using ...[2] = "true" tries to execute the put method of the given object. While put is available in Maps like HashMaps or the scope maps, Vectors use set instead of put to change values. For that reason, you get the "action expression put(...) not supported" error. In contrast to this, it's no problem to get the variable with viewScope.MY_SCOPE[1][2] because the get method is availiable in both HashMaps and Vectors.
When storing arrays in scope variables, I like to put the value into a properly typed javascript variable, make edits, and then replace the scope variable with the updated value.
In your case I would do the following:
var tempVar = viewScope.MY_SCOPE.toArray(); //convert to array to make sure properly typed
tempVar[1][2] = true;
viewScope.put(MY_SCOPE,tempVar);
Update:
After testing your code along with mine, I too get the same error. To be honest, I never would have messed with multi dimensional arrays in the first place. This is a perfect opportunity to use an array of objects:
var tempVar = []; // initialize the array
tempVar.push({val1:"id0",val2:0,val3:true});
tempVar.push({val1:"id1",val2:1,val3:false});
tempVar.push({val1:"id2",val2:3,val3:true});
viewScope.put("MY_SCOPE",tempVar);
Then to change the desired value:
var tempVar = [];
tempVar = viewScope.get("MY_SCOPE");
tempVar[1].val3 = true;
viewScope.put("MY_SCOPE",tempVar)
I tested this method and it works fine.

Javascript Object inside of Object

I'm working with phylogentic trees and I want an object for the tree itself and then an object for each species, 4 species total. I'm trying to have the tree contain the species objects under tree.leaf and then assign an array of attributes to each species but through the tree object, because I'm randomizing the order of the species so I can't depend on species names but I can use leaf placement(Hope that makes sense). I'm having trouble updating the html, a div inside a table though.
Simplified Version:
var tree = new Object();
var speciesA = new Object();
tree.leaf1 = speciesA;
//Not sure if this next line assigns to speciesA or what exactly happens
tree.leaf1.attributes = new Array("Attr1","Attr2",etc);
var count = 1;
for(attr in speciesA.attributes)
{
//There are 4 divs per speices to display attributes
document.getElementById("A"+String(count)).innerhtml = speciesA.attributes[attr];
count++;// used to specify divs ie A1 = attribute1, A2 = attribute2 etc
}
So I guess my main question is will this work/do what I think it does?
If needed I can pastebin my html and full js files.
What you have should work, but it can be written a bit cleaner. I would suggest this:
var tree = {
leaf1: {attributes: ["Attr1", "Attr2"]}
};
var attributes = tree.leaf1.attributes;
for (var i = 0; i < attributes.length; i++) {
document.getElementById("A"+(i+1)).innerHTML = attributes[i];
}
Things I changed:
Used a javascript literal to make the definition a lot more compact
Used {} and [] for defining arrays and objects rather than new Object() and new Array().
Used for (var i = 0; i < xxx.length; i++) syntax to iterate array elements only, not all properties. This is the "safe" way to iterate elements of an array.
Remove the String(count) as it is not needed. Javascript will auto-convert a number to a string when adding to another string.
Cached the value of the attributes array to save having to deep reference it each time.
Removed separate count variable as the for index can be used
To answer one of your other questions, when you do this:
tree.leaf1 = speciesA;
you have assigned a "reference" to speciesA to tree.left1. A reference is like a pointer. It is not a copy. So, the both refer to exactly the same object. Any change you make to speciesA or to tree.leaf1 is make a change to the exact same object.
So, when you then do this:
//Not sure if this next line assigns to speciesA or what exactly happens
tree.leaf1.attributes = new Array("Attr1","Attr2",etc);
you are indeed modifying the speciesA object since speciesA and tree.leaf1 point to the same object.
In javascript, arrays, objects and strings are assigned by reference. That means that when you assign one to a variable, it just points to the original object. A copy is not made. So, change the object via either either one will change the other (since they both point to the same object). Strings are immutable (a string is never actually changed). Things that feel like modifications to a string always just return a new string so this aspect of javascript doesn't affect strings so much. But, it is very important to know that arrays and objects are assigned by reference.

Javascript array becomes an object structure

I'm experiencing an odd behavior (maybe it isn't odd at all but just me not understanding why) with an javascript array containing some objects.
Since I'm no javascript pro, there might very well be clear explanation as to why this is happening, I just don't know it.
I have javascript that is running in a document. It makes an array of objects similar to this:
var myArray = [{"Id":"guid1","Name":"name1"},{"Id":"guid2","Name":"name2"},...];
If I print out this array at the place it was created like JSON.stringify(myArray), I get what I was expecting:
[{"Id":"guid1","Name":"name1"},{"Id":"guid2","Name":"name2"},...]
However, if I try to access this array from a child document to this document (a document in a window opened by the first document) the array isn't an array any more.
So doing JSON.stringify(parent.opener.myArray) in the child document will result in the following:
{"0":{"Id":"guid1","Name":"name1"},"1":{"Id":"guid2","Name":"name2"},...}
And this was not what I was expecting - I was expecting to get the same as I did in teh parent document.
Can anyone explain to me why this is happening and how to fix it so that the array is still an array when addressed from a child window/document?
PS. the objects aren't added to the array as stated above, they are added like this:
function objTemp()
{
this.Id = '';
this.Name = '';
};
var myArray = [];
var obj = new ObjTemp();
obj.Id = 'guid1';
obj.Name = 'name1';
myArray[myArray.length] = obj;
If that makes any difference.
Any help would be much appreciated, both for fixing my problem but also for better understanding what is going on :)
The very last line might be causing the problem, have you tried replacing myArray[myArray.length] = obj; with myArray.push(obj);? Could be that, since you're creating a new index explicitly, the Array is turned into an object... though I'm just guessing here. Could you add the code used by the child document that retrieves myArray ?
Edit
Ignore the above, since it won't make any difference. Though, without wanting to boast, I was thinking along the right lines. My idea was that, by only using proprietary array methods, the interpreter would see that as clues as to the type of myArray. The thing is: myArray is an array, as far as the parent document is concerned, but since you're passing the Array from one document to another, here's what happens:
An array is an object, complete with it's own prototype and methods. By passing it to another document, you're passing the entire Array object (value and prototype) as one object to the child document. In passing the variable between documents, you're effectively creating a copy of the variable (the only time JavaScript copies the values of a var). Since an array is an object, all of its properties (and prototype methods/properties) are copied to a 'nameless' instance of the Object object. Something along the lines of var copy = new Object(toCopy.constructor(toCopy.valueOf())); is happening... the easiest way around this, IMO, is to stringency the array withing the parent context, because there, the interpreter knows it's an array:
//parent document
function getTheArray(){ return JSON.stringify(myArray);}
//child document:
myArray = JSON.parse(parent.getTheArray());
In this example, the var is stringified in the context that still treats myArray as a true JavaScript array, so the resulting string will be what you'd expect. In passing the JSON encoded string from one document to another, it will remain unchanged and therefore the JSON.parse() will give you an exact copy of the myArray variable.
Note that this is just another wild stab in the dark, but I have given it a bit more thought, now. If I'm wrong about this, feel free to correct me... I'm always happy to learn. If this turns out to be true, let me know, too, as this will undoubtedly prove a pitfall for me sooner or later
Check out the end of this article http://www.karmagination.com/blog/2009/07/29/javascript-kung-fu-object-array-and-literals/ for an example of this behavior and explanation.
Basically it comes down to Array being a native type and each frame having its own set of natives and variables.
From the article:
// in parent window
var a = [];
var b = {};
//inside the iframe
console.log(parent.window.a); // returns array
console.log(parent.window.b); // returns object
alert(parent.window.a instanceof Array); // false
alert(parent.window.b instanceof Object); // false
alert(parent.window.a.constructor === Array); // false
alert(parent.window.b.constructor === Object); // false
Your call to JSON.stringify actually executes the following check (from the json.js source), which seems to be failing to specify it as an Array:
// Is the value an array?
if (Object.prototype.toString.apply(value) === '[object Array]') {
//stringify

Creating multi-dimensional arrays in javascript, error in custom function

I was trying to define an array (including other arrays as values) in a single javascript statement, that I can loop through to validate a form on submission.
The function I wrote to (try to) create inline arrays follows:
function arr(){
var inc;
var tempa = new Array(Math.round(arguments.length/2));
for(inc=0; inc<arguments.length; inc=inc+2) {
tempa[arguments[inc]]=arguments[inc+1];
}
return tempa;
}
This is called three times here to assign an array:
window.validArr = arr(
'f-county',arr('maxlen',10, 'minlen',1),
'f-postcode',arr('maxlen',8, 'minlen',6)
);
However in the javascript debugger the variable is empty, and the arr() function is not returning anything. Does anyone know why my expectations on what this code should do are incorrect?
(I have worked out how to create the array without this function, but I'm curious why this code doesn't work (I thought I understood javascript better than this).)
Well from what your code does, you're not really making arrays. In JavaScript, the thing that makes arrays special is the management of the numerically indexed properties. Otherwise they're just objects, so they can have other properties too, but if you're not using arrays as arrays you might as well just use objects:
function arr(){
var inc;
var tempa = {};
for(inc=0; inc<arguments.length; inc=inc+2) {
tempa[arguments[inc]]=arguments[inc+1];
}
return tempa;
}
What you're seeing from the debugger is the result of it attempting to show you your array as a real array should be shown: that is, its numerically indexed properties. If you call your "arr()" function as is and then look at (from your example) the "f-county" property of the result, you'll see something there.
Also, if you do find yourself wanting a real array, there's absolutely no point in initializing them to a particular size. Just create a new array with []:
var tempa = [];
Your code works. Just inspect your variable, and you will see that the array has the custom keys on it. If not expanded, your debugger shows you just the (numerical) indixed values in short syntax - none for you.
But, you may need to understand the difference between Arrays and Objects. An Object is just key-value-pairs (you could call it a "map"), and its prototype. An Array is a special type of object. It has special prototype methods, a length functionality and a different approach: to store index-value-pairs (even though indexes are still keys). So, you shouldn't use an Array as an associative array.
Therefore, their literal syntax differs:
var array = ["indexed with key 0", "indexed with key 1", ...];
var object = {"custom":"keyed as 'custom'", "another":"string", ...};
// but you still can add keys to array objects:
array.custom = "keyed as 'custom'";

javascript array attributes passed by reference

in this example, it seems that we can use a variable (here "second") to fill the array myArray, as if second was a "reference" to myArray : is that really what happens here?
var myArray = [];
var second = myArray;
second.target = … //we fill the "second" variable
second.offsetX = …
second.offsetY = …
var target = myArray.target; //then we retrieve the result from myArray
if (target) {
Thanks
second was a "reference" to myArray : is that really what happens here?
Yes.
Objects—like arrays—in JavaScript are passed and assigned by reference.
From your example, myArray and second both point to the same object in memory.
Yes, this is exactly what happens here. When you (for example) push new elements to second, you can read them later from myArray.
BTW, I sense that you're doing something strange. Why do you set an offsetX on an array?
This is called a shallow copy. You have a reference (var second = ...) to the original array (var myArray = ...), they both are pointing to the same memory in the memory of the JavaScript virtual machine.
This way you can access the array either by second or myArray.
var myArray = [];
This is just an array declaration It is same as var myArray=new Array();
About Array Referencing:
var second = myArray;
We are pointing the variable second to myArray memory location. Here new Object second will be created point to content of myArray. So, if you read content of second. It will read the myArray. But, you edit/update the content of second, content of myArray will be copied into second and it will be modified. As Bakudan said, It is the shallow copy. See the example below,
var myArray=[10,20,30];
var second =myArray; //second will contain 23,45 and 100.
If we update the array second, second=[100,200,300]
Original contents will be cleaned and 100,200,300 will be written.
To append the content to array second without removing the original content, We need to use function push as below:
second.push(100);second.push(200),second.push(300);
Now, content of second will be 10,20,30,100,200,300.
Object Property:
second.target = "testString";
second.offsetX =87;
second.offsetY =56;
This is the creation of object properties. It is same as,
second={"target":"testString","offsetX":87,"offsetY":56};
If you want to access value 87, it can be accessed as second.offsetX or second[offsetX].
More Information about java script Array is available here.

Categories