How does Javascript associative array work? - javascript

I am in bit of a puzzle, recently I had worked on a project where use of javascript was necessary. Everything is working fine I just need to know how does it work
eg : I had a dynamic variable count, which use to get some value, lets say I get the value as var count = 6;
Now when I put this in array {count : count }
I get the output as {count : 6}
Now my doubt is the output should have been { 6 : 6} as count should have been replaced with its value but it didn't happen so. Why is happening ? and how is this working properly ?

The key value pairs treat the key as a literal and the value as a variable.
so:
var count = 6;
var o = {count: count}; // results in {count: 6}
but to use a variable as the key, you can do this:
var count = 6;
var o = {};
o[count] = count; // results in: {6: 6}

The JavaScript object initialisation syntax lets you use bare words. If you do this:
{ foo: 6, bar: 12 }
It's equivalent to this:
{ 'foo': 6, 'bar': 12 }
What you want is to assign directly, like so:
var foobar = {};
foobar[foo] = 6;
foobar[bar] = 12;

In JavaScript associative arrays (or most associative arrays for that matter), the left side is the key, and the right side is the value. -> {key:value}
When you put {count:count} when you have a count variable beforehand (let's say its value is 10), what will happen is it will be read as {count:10}.
The left-hand side, or the key, is not a variable, but a constant.

Related

How to assign a series of variables with similar name

I declared six variables:
let L1, L2, L3, R1, R2, R3
and then I want to assign these six variables with the same value:
L1 = "something";
L2 = "something";
L3 = "something";
R1 = "something";
R2 = "something";
R3 = "something";
There must be a shorter way to do this right? I want to do it in a loop, because in this example we only have six variables, but in fact I have a lot of them.
The main way I see you being able to accomplish this is using an object (as others have already pointed out). You will still need to instantiate all the variables initially using the long-form syntax; but then you will be able to use a "for in" loop to actually assign all of the necessary values:
let something = {
L1: null,
L2: null,
L3: null,
};
for (let prop in something){
something[prop] = 1;
};
console.log(something);
Hope this helps!
I will directly answer your question, even though I think you shouldn't do that, you should think in a more "javascript" way of doing this.
That said:
const value = "something";
const numberOfVars = 100;
for( let i=0; i< numberOfVars; i++)
eval( "L"+ i + " = value" );
That would create the variables L0 to L99 with the value "something" inside. You could do that for any name, be it R, L or any string which is a valid javascript variable name.
Why not use an object instead?
const bubbles = {
bubbleL1,
bubbleL2,
bubbleL3,
bubbleR1,
bubbleR2,
bubbleR3
};
If you want to use array methods on it, you can extract an array of the values from the object with Object.values.
For your new question, you can fill an array with values, then destructure:
const [L1, L2, L3, R1, R2, R3] = new Array(6).fill('something');
console.log(L1);
console.log(R3);
If you want to give each variable its own name, but also have them grouped together so that you can use a blanket statement to set all their values, you got two easy options:
Option 1:
Use an array. An array will not allow you to name your variables, but they will be auto-assigned "names" according to their position (index) in the array. For example, if you made an array of the following values: "Cookie", "Money", and "Nothing." then they would be assigned numbers to reference them by, "Cookie" would be named "0", "Money" would be named "1", "Nothing." will be named "2" and so on... Here's an example of what an array looks like:
var nameOfArray = ["value1","value2","value3"];
and to access the value of an array, simply use that value's index:
nameOfArray[0]
(^^^ This would return "value1" ^^^)
So, if you think about it, that makes arrays very for-loop-friendly, so therefor this example looks very simple. Simply use the following to assign every variable in your array to the same value:
for(let i = 0;i < nameOfArray.length;i++){
nameOfArray[i] = "Whatever value I want.";
}
Option 2:
Use an object. An object is basically a group of named variables. The name of the variable is called the "key" and the value of the variable is called the "value". This is usually called a "key/value pair" For example:
var nameOfObject = {
variable1: "value1",
variable2: "value2",
};
Where "variable2" is a key, and "value2" is a value.
Then you can access each variable inside the object using simple dot or bracket notation.
Dot notation: nameOfObject.variableName
Bracket notation: nameOfObject["variableName"]
Setting all variables inside an object to the same value can be tricky. To do so, I usually use a for loop that iterates through all the keys in an object, and sets their values. In order to do so, you will first need to collect all the names of all the keys in the object. I simply use: Object.keys(nameOfObject) then I iterate through that array and assign each variable a value:
const objectKeyNames = Object.keys(nameOfObject);
for(let i = 0;i < objectKeyNames.length;i++){
nameOfObject[objectKeyNames[i]] = "Whatever I want to set it to.";
}
And it's that simple! All variables inside the object will be set to "Whatever I want to set it to."
it sounds like you are looking for a map rather than a list.
if you declare an object
var bubbles = {}
you can then access items by name
bubbles['bubbles1'] = 'something';
you can also loop through the items like a list later if you need to.
you can assign using left hand assignment like this:
let L1 = L2 = L3 = R1 = R2 = R3 = "something";
however that will cause a scope issue.
it would be better to declare then assign like
let L1, L2, L3, R1, R2, R3;
L1 = L2 = L3 = R1 = R2 = R3 = "something";`
Are you sure that you have like hundred variables that are not in fact parts of object?
Like let R1,R2,R3,L1,L2,L3 could be volume {left, right} for 3 audio track.
So you can write
let tracks = [{ right : 0, left : 0}, { right : 0, left : 0}, { right : 0, left : 0}]
L1 will become tracks[0].left and R3 will become tracks[2].right
With 100 tracks?
let tracksCount = 100;
let tracks = new Array(tracksCount).fill().map( t => ({ right:0, left: 0 }) );
Helping?

How do I call for a certain variable or another depending on a string I have

I have two variables, varL and varR, which have the information that they are L and R respectively. Depending on wether a third object has as imput 'L' or 'R', I would like to reference varL or varR respectively. Is there any way to do this?
Specifically, varL and varR are arrays. If the third object has as imput 'L', I would like to have access to varL[i] for some i, and the same goes for 'R'. I know this is not even remotely correct, but I was looking for something like
(var +'L')[i] or something
var varL;
var varR;
function getInput(input) {
return (input == 'L') ? varL : varR;
}
?
If you have input value then you can check and use corresponding array like below in your loop
var testL=[4,5,6];
var testR=[4,5,6];
var input='L';
if(input=='L'){
console.log(testL[0]); //replace 0 with i index
}else if(input=='R'){
console.log(testR[0]); //replace 0 with i index
}
Your question is the XY problem. Instead of asking "How can I access a variable by a dynamic name?", you should be asking "How can I access the needed value for L or R dynamically?"
One simple way to make it work is to store the values in an object with .L and .R properties. Then it's very simple to access the needed value:
var myVar = {
L: [1, 2, 3],
R: [3, 4, 5]
};
var direction = 'L';
console.log(myVar[direction]);
direction = 'R';
console.log(myVar[direction]);
Try to access it from window object
window[("var"+"L")]
It will work !!
or eval
eval(("var"+"L"))[i]

Javascript associative array how to map multiple strings to a number

Javascript newbie here. I currently have an associative array in the following format:
StringA: number,
StringB: number
Is it possible to map multiple strings to the same number? Something like this (some numbers may have a different number of Strings mapped to them):
StringA, StringB, StringC: number,
StringD, StringE: number,
StringF, StringG, StringH, StringI: number
Basically, I want holder to have the same value whether I write var holder = arr[StringA] or var holder = arr[StringC]. If it's not possible could someone point me in the right direction? Any help would be greatly appreciated!
You could use an object with a value for the object with multiple keys for one object.
Basically this creates a reference to the shared object. Then you could change the value inside of the object.
var temp = { value: 42 },
object = {
a: temp,
b: temp,
c: temp
};
console.log(object.a.value); // 42
object.b.value = 7;
console.log(object.c.value); // 7
Basically Js don't have associative array they are objects. Read this:
http://www.w3schools.com/js/js_arrays.asp
You need pointers to achive this, but JS not have pointers. But ther is a way to use pointers: use objects.
var assoc = [];
assoc["stringA"] = { value: 1};
assoc["stringB"] = assoc["stringA"];
assoc["stringC"] = assoc["stringA"];
assoc["stringD"] = { value: 10};
assoc["stringE"] = assoc["stringD"];
console.log("A: "+assoc["stringA"].value);
console.log("B: "+assoc["stringB"].value);
console.log("C: "+assoc["stringC"].value);
console.log("D: "+assoc["stringD"].value);
console.log("E: "+assoc["stringE"].value);
console.log("======== modify value ======");
console.log("\nModify A to 2")
assoc["stringA"].value = 2;
console.log("B: "+assoc["stringB"].value);
console.log("C: "+assoc["stringB"].value);
console.log("\nModify E to 20")
assoc["stringE"].value = 20;
console.log("D: "+assoc["stringD"].value);
console.log("E: "+assoc["stringE"].value);

Understanding kinda weird javascript array notation

In a script I saw this:
function addToPoint(x, y) {
x = Math.floor(x/SCALE);
y = Math.floor(y/SCALE);
if (!points[[x,y]]) {
points[[x,y]] = 1;
} else if (points[[x,y]]==10) {
return;
} else {
points[[x,y]]++;
}
drawPoint(x*SCALE,y*SCALE, points[[x,y]]);
}
So what's happening, I think, is this:
points[[x,y]] = 1;
Here, the guy dynamically creates a field for the points-object (which was declared empty). By passing it like this, it gets converted to a string and the x and y params of the function will make up that field.
So, in effect, if i called addToPoints(3,4) the code results in this:
points["3,4"] = 1;
This is really weird to me: is [x,y] a legit array? What kinda notation is that? What's the rule behind that??
I played around with the code a bit and it seems like you can declare an array in JavaScript just by doing this:
[x,y];
Help, tips and clarification appreciated!
var arr = [ x, y ]; is simply how you declare an array in JavaScript with x and y as the first and second elements.
The second part points[[x,y]] is a little more confusing. Basically what happens is that the arr array gets converted into a string (something like [ 1, 2, 3 ] will become "1, 2, 3") which will then be used as the property name on the points object.
A little less terse (and with actual numbers instead of the x and y parameters) what happens looks somewhat like this:
var points = {};
var arr = [ 1, 3 ];
var key = arr.toString(); // '1, 3'
points[key] = 1; // { "1, 3": 1 }
I believe what you miss here is the fact that when you use something as a property name on a project it being converted to the string:
points[[x,y]]
really doing
points[[x,y].toString()]
You can try to test it with
points[{}]
it will create key [object Object]
Reason to use it is that there is no support for two-dimensional arrays in javascript, however you can have array of arrays
And this little trick allow to use one dimensional array as a two-dimensional.
Here is funny trick:
Array.prototype.toString = function ( ) { return this.join(':') }
Now
points[[x,y]] = 1
will create key x:y and not x,y

How to access multiple properties of a javascript object?

If I have the array:
my_array = [{a:3,b:4,c:7},{a:5,b:8,c:6}]
property_names = ["a","c"]
How can use the property_names array against my_array to get the following output?:
subset_array = [[3,7],[5,6]]
var my_array = [{a:3,b:4,c:7}, {a:5,b:8,c:6}];
var keys = ['a', 'c'];
my_array.map(function(d){
return keys.map(function(k) {
return d[k];
});
});
This will give you [[3, 7], [5, 6]] and seems to be just what you want.
[Obsolete initial answer; before the OP updated his question]
Use o.a and o.c - no magic involved and no kittens harmed!
You could also use the [] syntax: o['a'] and o['c'] - but usually you only use it if you want to access a dynamic property name (i.e. a variable instead of a quotes string inside the [])
If you want an array with both values:
var a_and_c = [o.a, o.c];
Now you can use a_and_c[0] and [1] to access those two values.
You can access the properties by two notations:
Either o.a and o.c or o['a'] and o['c'].
EDIT
If you want to create a new array containing both values, then just do so using, e.g, the code suggested by #Reid :
[o.a, o.c]
2nd EDIT
So just build your array up inside the map function like the following:
var filter = [ "a","c","f","zzz"]; // should
subset_array = my_array.map( function(v){
var newArr = [];
for( var i=0; i<filter.length; ++i ) {
if ( typeof v[ filter[i] ] !== 'undefined' ) {
newArr.push( v[ filter[i] ] );
}
}
return newArr;
} );
One thing to note is, however, that as long as you use primitive types (like the int values in the example) the above code will clone the properties. This means, if you change a value in my_array at some point, subset_array will not be changed implicitly, but you have to recreate subset_array or adjust the value there, too.
This is not a full answer, however I believe it will be of use:
var values = []
var obj = {a: 1, b: 2, c: 3}
for (var prop in obj) {
if (obj.hasOwnValue(prop)) { // skip props in [[prototype]], no effect here
values.push(obj[prop])
}
}
values // -> [2, 1, 3] (in SOME UNDEFINED ORDER)
Key points:
Iterate [all] object property names for the object (but not [[prototype]] chain)
Access value dynamically from property name
Properties are not ordered; sort values if needed, for instance
This can be expanded to add different "exclusion" rules, for instance. It can also be adapted to different higher-order functions.
Happy coding.

Categories