Multiple object properties assignment in Javascript - javascript

Is there some kind of shorthand for this?
object.position.x = position.x
object.position.y = position.y
object.position.z = position.z
object.rotation.x = rotation.x
object.rotation.y = rotation.y
object.rotation.z = rotation.z
Thanks for your time.

Yes you can use Object.assign().
var obj = {}
var position = {x: 1, y: 2, z: 3}
var rotation = {x: 1, y: 2, z: 3}
obj.position = Object.assign({}, position);
obj.rotation = Object.assign({}, rotation);
console.log(obj)
If you only want to take specific properties from object you can create your pick function using map() to get array of objects and later use spread syntax to assign each object.
var obj = {}
var position = {x: 1, y: 2, z: 3}
var rotation = {x: 1, y: 2, z: 3}
function pick(obj, props) {
return props.map(e => ({[e]: obj[e]}))
}
obj.position = Object.assign({}, ...pick(position, ['x', 'y']));
obj.rotation = Object.assign({}, ...pick(rotation, ['x', 'y', 'z']));
console.log(obj)

You could use a direct approach by assigning the objects directly,
object.position = position;
object.rotation = rotation;
or with an array and the keys with iterating the properties.
['x', 'y', 'z'].forEach(function (k) {
object.position[k] = position[k];
object.rotation[k] = rotation[k];
});

With ES6 Spread Operator you can do it easier in one line, for the question sample:
object = {...object, position, rotation}
Just notice it will replace new properties with old one

My advice: DON'T USE ANY "CLEVER" LOOPS AND DYNAMIC SH*T
Reasons:
It's just a few lines, not a ton of lines, don't do overengineering
It's so much readable, that even IDE can help you with autosuggestions

You can also use a for...in loop, it's simple and quite readable. Example:
for ( const property in position ) {
object.position[property] = position[property];
}
MDN reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in

Related

How to apply Math or a function to every element in a JavaScript object

I have an object in js: {x: 0, y: 0}, and I want to increment both x and y by one. Now, this isn't a big object, so I can just use placeholder.x and placeholder.y, not very hard. But if I wanted to add more things to the object, the code would get very long and repetitive, so is there a shorter way to apply functions or math to everything in an object?
You can use Object.keys to get an iterable Array of the Object's keys, then use that to loop each and perform the functions you desire:
const myObject = {x: 1, y: 1};
for (key of Object.keys(myObject)) {
myObject[key]++;
}
console.dir(myObject);
In production-grade code, you should check to ensure that the data you're attempting to modify is numerically-typed so you don't end up inadvertently attempting to increment a non-numeric value:
const myObject = {x: 1, y: 1};
for (key of Object.keys(myObject)) {
if (typeof myObject[key] === 'number') myObject[key]++;
}
console.dir(myObject);
You can loop on an object by using Object.keys():
const p1 = {
x: 0,
y: 0
}
function translateXYbyN(p, n) {
Object.keys(p).forEach((c) => p[c] = p[c] + n);
}
console.log(p1);
translateXYbyN(p1, 1);
console.log(p1);
Also, you can also provide a key map in order to manipulate only the wanted keys:
const p2 = {
x: 0,
y: 0,
name: "point"
}
function translateXYbyN(p, n, mask) {
Object.keys(p).forEach((c) => {
if(mask.includes(c))
p[c] = p[c] + n
});
}
console.log(p2);
translateXYbyN(p2, 1, ['x','y']);
console.log(p2);
you can make a function:
const incObj = o => { ++o.x; ++o.y }
const placeholder = {x: 1, y: 1}
incObj( placeholder )
console.log( placeholder )

Is it possible to destructure an object into existing variables?

I am trying to extract variables using object destructuring but those variables already exist, something like this
const x=1, y=2 // Those should be 1 and 2
const {x,y} = complexPoint
const point = {x,y}
Is there any way to do this without renaming the destructuring variables?.
Some like this and updating point avoiding const definition?
const point = {x,y} = complexPoint
The expected result should be as using object destructuring
const x=1, y=2 // Those should be 1 and 2
const point = {
x:complexPoint.x,
y:complexPoint.y
}
You can do this with array destructuring, i.e.:
const complexPoint = [1,2];
let x, y;
[x,y] = complexPoint;
As for object destructuring, an equivalent syntax would not work as it would throw off the interpreter:
const complexPoint = {x:1,y:2};
let x, y;
{x,y} = complexPoint; // THIS WOULD NOT WORK
A workaround could be:
const complexPoint = {x:1,y:2};
let x, y;
[x,y] = [complexPoint.x, complexPoint.y];
// Or
[x,y] = Object.values(complexPoint);
UPDATE:
It appears you can destructure an object into existing variables by wrapping the assignment in parenthesis and turning it into an expression. So this should work:
const complexPoint = {x:1,y:2};
let x, y;
({x,y} = complexPoint); // THIS WILL WORK
here it can be done like this.
const complexPoint = {x: 1, y: 2, z: 3};
const simplePoint = ({x, y}) => ({x, y});
const point = simplePoint(complexPoint);
console.log(point);
In a single line looks like this:
const complexPoint = {x: 1, y: 2, z: 3};
// can be written as
const point2 = (({x, y}) => ({x, y}))(complexPoint);
console.log(point2);
It's not 100% clear to me what you want to do.
If you want to update point with two properties of complexPoint
You can actually destructure an object into anything that is assignable. Most often you will destructure into variables, but you can also destructure into properties.
Example:
const point = {x: 1, y: 2};
const otherPoint = {x:3, y: 4};
({x: point.x, y: point.y} = otherPoint);
// ^ ^
// parenthesis are necessary otherwise the runtime will interpret {
// as the start of a block
console.log(point);
Of course this can become difficult to read the more properties you have. You can also just assign them directly, the good old fashioned way:
point.x = otherPoint.x;
point.y = otherPoint.y;
Or with a loop:
for (const prop of ['x','y']) {
point[prop] = otherPoint[prop];
}
If you want to create a new object from an existing object
Create a helper function to "pick" the properties from the existing object. Such a function is provided here.
const point = pick(otherPoint, 'x', 'y');
After the destructuring, you can use the destructured data and save it as an object to another variable.
If we have this object:
const obj={"property":"value","property2":"value"};
You can destructure data from it like this:
const {property}=obj;
If we want to assign the destructured data only to another variable, We would do this:
const newVariable ={property};
Now the newVariable value will be equal to:
{"property":"value"}

How JS object literals or arrays determine whether to create certain attributes based on judgment

My expression may not be clear, Is the following code abbreviated
let a = true;
let obj = {
x: 1,
y: 2
}
if(a){
obj.z = 3
}
or
let a = true;
let arr = ['a', 'b'];
if(a){
arr.push('c')
}
arr = arr.concat('d','e')
Maybe I am too lazy, but I still want to ask, I don’t know how to search for this problem on Google.
Objects
You can't (reasonably) optionally create an object property in an object initializer based on a flag. The way you have it in your first example is how you'd do that.
The unreasonable way is with spread notation (ES2018+ for objects) and the conditional operator:
let obj = {
x: 1,
y: 2,
...(a ? {z: 3} : {})
};
Example:
let a = true;
let obj = {
x: 1,
y: 2,
...(a ? {z: 3} : {})
};
console.log(obj);
If you can't rely on object spread (it is quite new), you'd use Object.assign instead (again, if we're being unreasonable :-) ):
let obj = Object.assign({
x: 1,
y: 2
}, a ? {z: 3} : null);
Example:
let a = true;
let obj = Object.assign({
x: 1,
y: 2
}, a ? {z: 3} : null);
console.log(obj);
Arrays
You can't (reasonably) optionally create an entry in an array initializer based on a flag. You'd want to do it as you've shown.
As with objects, the unreasonable way is with spread notation (ES2015+ for arrays) and the conditional operator:
let arr = ['a', 'b', ...(a ? ['c'] : []), 'd', 'e'];
Example:
let a = true;
let arr = ['a', 'b', ...(a ? ['c'] : []), 'd', 'e'];
console.log(arr);

snippet for creating object from destructured array

For example, I had an array with 3 numbers:
var arr = [124, -50, 24];
and I need to convert this array to the object:
{
x: 124,
y: -50,
z: 24
}
I don`t want to use "old-style" syntax for this, for example:
{
x: arr[0],
y: arr[1],
z: arr[2]
}
so for now, I`m using that syntax:
const [x, y, z] = [...arr];
const obj = {x, y, z};
But, is there is any way to do this with a straight dectructuring array to object without need of temporary variables?
As it was already mentioned in the comment you can use an Immediately Invoked Function Expression (IIFE) to create the object in a single step, but it's less readable then multiple steps.
const arr = [124, -50, 24];
const obj = (([x, y, z]) => ({ x, y, z }))(arr);
console.log(obj);
You can also do
const obj = {};
([obj.x, obj.y, obj.z] = arr);
to avoid the temporary variables, but I'd question whether that's an improvement.
Just use this
let obj = {...arr}

initializing in loop array with objects

I want to create such array in loop
dataset: [
{
x: 0,
y: 0,
},
{
x: 1,
y: 0.993,
}
]
But this way is not correct.
var array = new Array(10);
for (var i = 0; i < 5; ++i) {
array[i].x = 1;
array[i].y = 2;
}
How I can initialize in correct way?
The comments made by SLaks and squint are correct, so this answer is more of an explanation of why your code isn't working like you think it should, and an example of what you could do instead.
You created an array with room to hold 10 things but you didn't specify what those things were and so nothing is contained in the array.
var array = new Array(10);
you can visualize your array like this:
array = [undefined, undefined, undefined, undefined,...
The array you created was just a container for 10 things not yet defined. When you tried to assign the 'x' and 'y' properties of the array elements, you were were trying to operate on something that did not exist. To get what you want, I suggest creating an object that has the properties you want, with initial values, and then use your loop to add the number of elements you want.
var array = [];
var arrayObject = {x:0,y:0};
for(i=0; i < 10; i++){
array.push(arrayObject);
}
You can do this job in one assignment line as follows;
var dataSet = (new Array(10)).fill("initial y value").reduce((p,c,i) => p.concat({x:i,y:c}),[]);
console.log(dataSet);
I just couldn't figure what y values you would like to have so inserted the initial values of the array. Change them the way you like later. I hope it helps.
Replace the new Array(10) with
var array = Array.apply( {}, { length: 10 } ).map( function() { return {} });
new Array(10) is creating an array like
[ undefined, undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined]
So you are trying to assign x on undefined
If you tried
new Array(10).map(function(){ return {}; }) it will not work either.
An es6 way to do it would be
Array.from(new Array(10), () => { return { x: 1, y: 2 }; })
In JavaScript the Array acts different than in static-typed languages, so there's no need to initialize it with fixed length.
For ECMAScript 6 specification and later:
var points = [].fill.call({ length: 5 }, {x: 1, y: 1});
It produces
[{x: 1, y: 1},
{x: 1, y: 1},
{x: 1, y: 1},
{x: 1, y: 1},
{x: 1, y: 1}]
To ensure old browsers' support use for loop:
var points = [{x: 1, y: 1}];
for (var i = 0; i < 5; i++) points.push(points[0]);

Categories

Resources