Reference Array Elements in JavaScript - javascript

Let's say I have the following code in JavaScript:
var x = 2;
var myArray = [0,1,x];
x = 3;
Changing the value of x would leave myArray completely unchanged, so myArray[2] would still be 2.
How could I set it up so that I can change the element at myArray[*wherever x is*] repeatedly without actually knowing the index?

You could define a getter that acts as a reference to the live variable:
var myArray = Object.defineProperty([0,1], 2, {
get() { return x },
enumerable: true,
configurable: true
});
var x = 2;
console.log(myArray);
x = 3;
console.log(myArray);
Of course, this is a horrible thing to do to an array, and will probably incur heavy performance penalties in every place where the array is used. So: don't do this. Just assign to myArray[2] instead of x in every place, or use a getter/setter function pair instead of the x variable that does this.
function setX(v) { myArray[2] = v; }
var myArray = [0,1,2];
setX(2);
console.log(myArray);
setX(3);
console.log(myArray);

You could put your value in an object.
var x = {
value: 2
}
var myArray = [0,1,x];
console.log(myArray[2].value); // 2
x.value = 3;
console.log(myArray[2].value); // 3
In this case you are always pointing to the same object, the content of which can change at any time.

Related

Why can't I access the [0][0] position of my 2 dimensional array created with 'new Array' constructor?

I need to create a function that receives a height and a width and creates a 2 dimensional array. My function seems to be achieving this but then when I try to change position [0][0] of the created array it changes all first positions of my inner arrays (see snippet for more clarity).
What am I doing wrong?
function createArr(height, width) {
return new Array(height).fill(new Array(width).fill(1));
}
const myArr = createArr(3,2)
console.log(myArr)
//Expected output: [[1,1],[1,1],[1,1]]
myArr[0][0] = 5;
console.log(myArr)
// Expected output: [[5,1],[1,1],[1,1]]
// Real output: [[5,1],[5,1],[5,1]]
The problem is that the same array reference created with new Array(width).fill(1) is being passed for all heights. Hence if you change any array, it seems like all arrays have change but actually its the same array whose reference is being passed for all height. Hence for every height you need to use new Array() constructor to create separate arrays for each height
function createArr(height, width) {
const arr = [];
for(let i=0; i<height; i++){
// You need to create new array for every height
arr[i] = new Array(width).fill(1);
}
return arr;
}
const myArr = createArr(3,2)
console.log(myArr)
//Expected output: [[1,1],[1,1],[1,1]]
myArr[0][0] = 5;
console.log(myArr)
// Actual output: [[5,1],[1,1],[1,1]]
const val = 1;
function createdArr(R,C) {
var arr = Array(R);
for (var i = 0; i < R; i++) {
arr[i] = Array(C).fill(val);
}
return arr;
}
var ary = createdArr(3,2);
console.log(ary);
ary[0][0]=5;
console.log(ary);
UPDATE: Little late to post, #Rishabh has already answered with reason.

Convert javascript object keys to real int after JSON encoded

I have this:
var a = {};
a[1] = 1;
a[4] = 4;
console.log(JSON.stringify(a));
then I get:
{"1":1,"4":4}
but I want to get:
{1:1,4:4}
how to reach this? In other words, I want to keys be real int.
When you call JSON.stringify() method it creates a valid JSON string.
One of the rules for valid JSON is that every property should be in "quotes".
So thats why it is impossible to get such result as you want using JSON.stringify.
If you want to just convert such object to array it is possible, for example usin such function.
function numerableObjectToArr(obj) {
var result = [];
var keys = Object.keys(obj);
keys.forEach(function(item){
result.push(obj[item]);
})
return result;
}
var a = {};
a[1] = 1;
a[4] = 4;
numerableObjectToArr(a); // returns [1, 4]
But in this way you will just receive Array with values of existing properties in the obj.
But if your prop name means the index in the array, and you are sure that there will be always number as a prop name - you can improve this function:
function numerableObjectToArr(obj) {
var result = [];
var keys = Object.keys(obj);
keys.forEach(function(item){
result[+item] = obj[item]; //we put index, then we put value to that place in array
})
return result;
}
var a = {};
a[1] = 1;
a[4] = 4;
numerableObjectToArr(a); // returns [undefined, 1, undefined, undefined, 4]
I'm not sure you can do what you're trying to do the as the keys have to be string values. I'd advise having string name for your keys (i.e 1 = One, 2 = Two, etc). You could then try this:
var a = {};
a.one = 1;
a.two = 2;
a.three = 3;
a.four = 4;
console.log(JSON.stringify(a));
I hope this helps.
var a = {};
a[1] = 1;
a[4] = 4;
alert(JSON.stringify(a).replace(/\"([0-9]+)\":/g, '$1:'));
But it is kludge. JSON - has a string keys.

How to turn an undefined var to an object, inside a function

There is something I can't find an answer or an explanation for. Let's take for example the following code:
function fn(x){
x = {value: 10};
}
var a;
fn(a);
alert(a.value); //a is undefined
Shouldn't a = {value: 10}; as we passed it through that function?
The x is locally scoped. You are passing only values and not references. So you might need to return and assign like this:
function fn(x){
x = {value: 10};
return x;
}
var a;
a = fn(a);
From an awesome article:
When passing in a primitive type variable like a string or a number, the value is passed in by value. This means that any changes to that variable while in the function are completely separate from anything that happens outside the function.
function myfunction(x)
{
// x is equal to 4
x = 5;
// x is now equal to 5
}
var x = 4;
alert(x); // x is equal to 4
myfunction(x);
alert(x); // x is still equal to 4
Passing in an object, however, passes it in by reference. In this case, any property of that object is accessible within the function.
function myobject()
{
this.value = 5;
}
var o = new myobject();
alert(o.value); // o.value = 5
function objectchanger(fnc)
{
fnc.value = 6;
}
objectchanger(o);
alert(o.value); // o.value is now equal to 6

How to convert a var in an array after it is created?

Working on my first JS app, BlackJack, and have been stuck at this point for a while: what I'm trying to do is if var a is called from the array it could = 11 or 1 depending on the total value. Is there no way to change the value of an item in an array after you set up said array?
var j = 10;
var q = 10;
var k = 10;
var a;
var totalPlayer = 12;
var cards = [2, 2, ..., a, a, a];
function processIt() {
playerCard1 = cards[48]; //this is calling for var a form the array
if (totalPlayer > 11) {
a = 1;
} else {
a = 11;
}
var cpu1 = document.getElementById("cpu1");
cpu1.innerHTML = playerCard1; //this is calling for var a form the array
}
I have also tried converting it to a sting then back to a var, failed.
If I'm reading correctly, you've set up your array
var cards = [2, 2, ..., a, a, a];
and now you want to change all those a's?
Unfortunately (since a is a primitive) you'll have to manually change the values in your array that currently equal a, and set them to the updated value.
for (var i = 0, max = cards.length; i < max; i++)
if(cards[i] === a)
cards[i] = newValue;
EDIT
As hop points out, just be aware that if a is equal to 2, then all indexes in your array equal to 2 will be replaced—those first few indexes that you manually set to 2, and also those indexes at the end that you set to a. But since you say that a will either be 1 or 11, it looks like you've set things up in such a way that this won't be an issue.
You cannot do what you are expecting this way.
var a = 1;
var cards = [2, 2, a, a, a];
a = 5;
alert(cards); // This should print 2,2,5,5,5 is what you expect.
// But, it will only print 2,2,1,1,1
You can store all the indexes for which you set the value as 'a'. After all, you are constructing the array and it should be no hurdle for you.
In our case, you will have another array
var aIndexes = [2,3,4];
Then you can change the value of cards array like below.
if (totalPlayer > 11) {
a = 1;
} else {
a = 11;
}
for(var i =0; i< aIndexes.length; i++){
cards[i] = a;
}
The following line:
var cards = [2, 2, ..., a, a, a];
...copies the value of a into the last three array positions. Those values have no relationship with a itself. Changing a later has no effect on the array. It must be updated manually:
if (totalPlayer > 11) {
a = 1;
} else {
a = 11;
}
cards.splice(-3, 3, a, a, a);
var a;
…
var cards = [2, 2, ..., a, a, a];
puts the value of a at the time of creation of the Array instance as element of the array, not some sort of pointer to a. It is equivalent here to
var cards = [2, 2, ..., undefined, undefined, undefined];
You can either modify the array directly, as others have pointed out, or store references to an Object instance in the array (references are values). Modifying a property of that Object instance would modify it for all references to the Object instance then.
var a = {
toString: function () { return String(this.valueOf()); },
valueOf: function () { return this.value; }
};
// …
var cards = [2, 2, ..., a, a, a];
function processIt()
{
var playerCard1 = cards[48];
if (totalPlayer > 11)
{
a.value = 1;
}
else
{
a.value = 11;
}
var cpu1 = document.getElementById("cpu1");
cpu1.innerHTML = playerCard1;
}
Accessing a in string or numeric expression context would then yield the value of the value property of the Object instance referred to by a:
/* y + a.valueOf() */
var x = y + a;
/* z + a.toString() */
var y = z + String(a);
You must decide whether either approach makes sense in your case, as I do not know Blackjack well, and your question is rather confused.
BTW, you have forgotten to declare playerCard1 which causes it to leak into outer execution contexts or causes a runtime error (ES 5.x strict mode). I have fixed it for you. In general, you want to reduce the number of global variables to the absolute necessary minimum.

javascript array set deep value

I have an array called insurances. I set data in this array like this:
var insurances = {};
insurances[0] = {}
insurances[0]['id'] = 0;
etc...
Later on i want to change the id by doing this:
insurances[index]['id'] = insuranceId;
The index = 0 and the insuranceId = 1000;
Somehow it doesn't set the value (i get undefined). What am i doing wrong?
Thanks for helping.
It works: http://jsfiddle.net/pNAwk/
var insurances = {};
insurances[0] = {}
insurances[0]['id'] = 0;
insurances[0]['id'] = 1000;
alert( insurances[0]['id'] ); // alerts 1000
Note that if you intend to use indexed property names (0, 1, 2, ...), then an array literal is more appropriate:
var insurances = [];

Categories