I have an array: {r=1, g=4, b=6} How do i go about getting the value of each (r,g,b) into a separate variable?
JavaScript does not have associative arrays. So this is legal:
var my_rgb_arr = [1, 4, 6]
Or this can be legal:
var my_rgb_obj = { r: 1, g: 4, b: 6 };
To access the array:
my_rgb_arr[0]; // r
my_rgb_arr[1]; // g
my_rgb_arr[2]; // b
And the object:
my_rgb_obj.r; // r
my_rgb_obj.g; // g
my_rgb_obj.b; // b
Which are you dealing with?
That's not an array
That's almost an object constant, but you need ":" instead of "="
The values already are in separate variables, or would be if the syntax was OK
That's the syntax for instantiating an "object constant" and populating it with properties and values. If you assign that value (the whole thing) to another variable, then you'll be able to get at the properties.
var rgb = { r: 1, g: 4, b: 6};
var rByItself = rgb.r;
In Javascript, {r:1, g:4, b:6} would be an object. Let's pretend your object is declared as such:
var obj = {r:1, g:4, b:6};
Then you could retrieve the values of r, g, and b in two ways.
Method 1:
var red = obj.r;
var green = obj.g;
var blue = obj.b;
Method 2:
var red = obj['r'];
var green = obj['g'];
var blue = obj['b'];
What you have: {r=1, g=4, b=6} could only be interpreted as a block in ECMAScript. It is therefore not an Array.
Arrays and Objects Example:
var myArray = [1, 4, 6];
var myObject = { r:1, g:4, b:6 };
Block Example:
var r, g, b;
if(true)
{r=1, g=4, b=6};
Code should be executable, as transmitted and the outcome of that code posted.
Related
The documentation on Map on mdn says
A Map's keys can be any value (including functions, objects, or any primitive).
Let's say we have
let a = new Map();
a.set({a: 1, b:3}, "Hello");
a.set({a: 1, b:3}, "World");
This produces a map with 2 elements instead of one.
How can I make the lookup of keys to be in terms of their values and not their ids?
Or alternatively, how can I make a Map where the key is a pair of unordered values?
The following is a workaround that will store things in the way you intend. Albeit, it does not use the Map class and the assigning function is not a method of any class.
set=function(a,o,v){a[[o.a,o.b].sort().join(",")]=v};
const a = {};
set(a,{a: 1, b:3}, "Hello");
set(a,{a: 3, b:1}, "World");
set(a,{a: 2, b:2}, "something else");
console.log(a)
First of all you need to understand that two object initialized with same values will never be equal to each other. Try running the following snippet.
Hence map creates two different elements with it.
var x = {a: 1, b:3};
var y = {a: 1, b:3};
var z = x;
console.log(x === y); // => false
console.log(x === z); // => true
Therefore, if you wish to group based on object as keys you will probably have to pass the objects as references as shown below:
let a = new Map();
let key = {a: 1, b:3};
a.set(key, "Hello");
a.set(key, "World");
console.log(a.get(key));
Alternatively instead of keeping track to references for each key, you can just stringify the object like so:
let a = new Map();
let key = JSON.stringify({a: 1, b:3});
a.set(key, "Hello");
a.set(key, "World");
console.log(a.get(key));
If I do this:
a = []
b = [1, 2, 3]
a = b
a will then refer to b
I want to copy all of the values in b into a without changing any memory address/references.
You could push the values without changing the reference from a or b.
var a = [],
b = [1, 2, 3];
a.push(...b);
If you want to populate a in-place, without ever discarding the initial array, then you can simply loop over b and add all the items in a:
var a = []
var b = [1, 2, 3]
var firstA = a; //get a initial element
b.forEach(function(item) {
this.push(item)
}, a);// <-- pass `a` as the `this` context
console.log("`a` is unchanged", a === firstA);
console.log("`a` is not `b`", a !== b);
console.log(a);
let a = b.map(x => x);
The .map() function will create a new array with values generated from the source elements via the passed-in callback function.
As noted in a comment
let a = b.slice();
is pretty much exactly the same.
Basically this saves you the step of
let a = [];
since one brand-new empty array is as good as another. However, if you really have your heart set on using the empty array explicitly initialized, you could use
b.forEach(x, i) { a[i] = x; });
A= b.slice(). It will create a shadow copy of element without changing original one. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
If:
var x = [1, 2, 3];
var y = [4, 5, 6];
var z = x;
and then if z[2] = y[0];
Why is it that console.log(x); is [1, 2, 4] and not [1, 2, 3]?
When you do var z = x; you are no creating a new array, entirely separate from x, you are simply creating a reference to the original array. Hence, the change happens in both.
If you want to create a new object, you can use the new ES6 spread operator
var z = {...x};
Have a look at this answer for a more in-depth explanation of passing by reference and by value.
Cuz the 'z' variable is a pointer to the same array that 'x' point to.
An array in JavaScript is also an object and variables only hold a reference to an object, not the object itself. Thus both variables have a reference to the same object. So changing made through one variable reflected in other as well.
var x = [1, 2, 3];
var y = [4, 5, 6];
var z = x;
z[2]=y[0];
console.log(x);
var w=Object.assign([],x);
w[0]=y[1];
console.log(x);
console.log(w);
Look at the example. If you want to change in a new variable and don't want reflected that change in original one than use Object.assign.
I am trying to use Array.prototype.push.apply to merge two lists.
c = Array.prototype.push.apply(a, b);
However, this does not merge the arrays when the second one is [].
for instance if
a = ['x', 'y', 'z']
b = []
c will be 3
Why is this happening?
Shouldn't [] be treated like any array?
Just use Array.prototype.concat:
c = a.concat(b);
It is perfectly correct, because Array.push() will return the length of the new array.
If you want a new array which has the concatenated value then use Array.concat() instead.
What you may have been trying to achieve is using push.apply to append b to a. However this method means that you don't have to create a new array c to hold the result.
var a = [1, 2, 3, 4], b = [5];
a.push.apply(a, b); // a = [1, 2, 3, 4, 5]
Your real problem is the .apply, it ask the contetx (a) and an array of values (b), if you pass an empty array it acts like you have passed no values...
Try this:
c = Array.prototype.push.call(a, b);
//c = 4
I created this object:
var keys = {A: 'a', B: 'b' };
Later I tried create this other object:
var values = {keys.A: 1, keys.B: 2};
However I got this in Firefox console:
SyntaxError: missing : after property id
Even when I tried:
var vals = {keys['A']: 1, keys['B']: 2}
I got the same error.
The only way to get a success is if I type this:
var vals= {};
vals[keys.A] = 1;
vals[keys.B] = 2;
So, my question is if there is a more elegant way (similar to the first try) to create an anonymous object using as keys the values from a pre-existent object.
Thanks,
Rafael Afonso
Yes, the more elegant way is to use ES6 syntax:
var values = {[keys.A]: 1, [keys.B]: 2};
The thing in brackets can be any expression, so run wild:
var values = { [createPropName() + "_prop"]: 42 }
This is called "computed (dynamic) property names". See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Computed_property_names.
try this
var keys = {A: 'a', B: 'b' },
foo = {};
for (key in keys) { foo[key] = keys[key] }
In an Object Initialiser, the property name must be one of:
IdentifierName
StringLiteral
NumericLiteral
You can do what you want in ES5 using an Object literal for the keys and an Array literal for the values:
var keys = {A: 'a', B: 'b' };
var values = [1, 2];
var obj = {};
Object.keys(keys).forEach(function(v, i) {
obj[v] = values[i];
});
console.log(JSON.stringify(obj)) // {"A":1,"B":2}
However, that isn't reliable because the object properties may not be returned in the order you expect, so you might get:
{"B":1,"A":2};
To do what you want in ES5 and guarantee the order, an array of keys and an array of values is required, so something like:
var keys = ['a', 'b', 'c'];
var values = [1, 2, 3];
var obj = {};
keys.forEach(function(v, i) {obj[v] = values[i]});
console.log(JSON.stringify(obj)) // {"a":1, "b":2, "c":3}