Destructure to two separate variables - javascript

Is there a quick way to destructure an object so that it store into two different groups? for example:
const obj = {a: 1, b: 2, c:3, d: 4, e: 5};
const {a, b} = obj;
// store the rest of the properties that weren't destructed above
const {otherStuff} = obj;
Some stuff to note:
I know what are the first properties i need from the object.
I don't know what the rest of the properties are that weren't destructured.

const {a, b, ...otherStuff} = obj;

You can use destructuring with rest parameter syntax ... to get the rest of the object in another variable:
const obj = {a: 1, b: 2, c:3, d: 4, e: 5};
const {a, b, ...otherStuff} = obj;
console.log(otherStuff);

Related

how do i destructure an object only when key is present

how do I destructure an object only when key is present in the object or should I say destructuring using conditionals
const arts = { a: 23, b: 3, c: 5}
const {a, d} = arts
console.log(d)
// result produces an error on execution
I want a code where "d" won't be destructured if it's not a key available in the object.
You could also try to use a default value for the properties like so:
const arts = { a: 23, b: 3, c: 5}
const {a = undefined, // The default could be 0 if it works for your use case.
d = undefined,
} = arts
console.log(d) // logs: 'undefined'
console.log(a) // logs: 23
const arts = { a: 23, b: 3, c: 5}
if(arts.hasOwnProperty('a')) {
const {a} = arts
console.log(a)
// do something with a
}
else {
console.log('a was not found in arts');
}
if(arts.hasOwnProperty('d')) {
const {d} = arts
console.log(d)
// do something with d
}
else {
console.log('d was not found in arts');
}
Using arts as defined above will output:
23
d was not found in arts
The hasOwnProperty() method returns a boolean indicating whether the object has the specified property as its own property (as opposed to inheriting it).

Object.assign(...as) changes input parameter

Object.assign(...as) appears to change the input parameter. Example:
const as = [{a:1}, {b:2}, {c:3}];
const aObj = Object.assign(...as);
I deconstruct an array of object literals as parameter of the assign function.
I omitted console.log statements. Here's the stdout from node 13.7:
as before assign: [ { a: 1 }, { b: 2 }, { c: 3 } ]
aObj: { a: 1, b: 2, c: 3 }
as after assign: [ { a: 1, b: 2, c: 3 }, { b: 2 }, { c: 3 } ]
The reader may notice that as first element has been changed in an entire.
Changing a new array bs elements to an immutable object (using freeze)
const bs = [{a:1}, {b:2}, {c:3}];
[0, 1, 2].map(k => Object.freeze(bs[k]));
const bObj = Object.assign(...bs);
leads to an error:
TypeError: Cannot add property b, object is not extensible
at Function.assign (<anonymous>)
Which indicates the argument is indeed being changed.
What really confounds me is that even binding my array, cs, by currying it to a function (I think you call this a closure in JS)
const cs = [{a:1}, {b:2}, {c:3}];
const f = (xs) => Object.assign(...xs);
const g = () => f(cs);
const cObj = g();
returns:
cs before assign: [ { a: 1 }, { b: 2 }, { c: 3 } ]
cObj: { a: 1, b: 2, c: 3 }
cs after assign: [ { a: 1, b: 2, c: 3 }, { b: 2 }, { c: 3 } ]
What went wrong here? And how may one safely use Object.assign without wrecking its first argument?
Object.assign is not a pure function, it writes over its first argument target.
Here is its entry on MDN:
Object.assign(target, ...sources)
Parameters
target
The target object — what to apply the sources’ properties to, which is returned after it is modified.
sources
The source object(s) — objects containing the properties you want to apply.
Return value
The target object.
The key phrase is "[the target] is returned after it is modified". To avoid this, pass an empty object literal {} as first argument:
const aObj = Object.assign({}, ...as);

How do I take all of an object's properties and insert them into its own object array property?

For example I want something like:
{
a: 1,
b: 2,
c: 3
}
turned into:
{
d: {
a: 1,
b: 2,
c: 3
}
}
I've tried assigning a new property to that object with the object itself but it shows up as circular so I figure it's a reference instead of the actual properties instead of the actual values. I want to try something like JSON.stringify the object and assign it to the property but I don't know how to turn that string into an object format that I can assign to the property.
let firstObj = {
a: 1,
b: 2,
c: 3
}
let secondObj = {};
secondObj.d = firstObj;
console.log(secondObj);
Basically you create a new object and assign the original object to its property d.
You can use ES6 destructuting to make a shallow copy of the object and put it on a new prop:
let obj = {
a: 1,
b: 2,
c: 3
}
obj.d = {...obj}
console.log(obj)
If that's not an option you can reduce() over the objects keys to make a new object and assign it to d:
let obj = {
a: 1,
b: 2,
c: 3
}
obj.d = Object.keys(obj).reduce((newObj, k) => {
newObj[k] = obj[k]
return newObj
},{})
console.log(obj)
It depends whether you want to make the deep or shallow copy of the object d. (Can the object d have a nested structure?)
The question about efficient ways to clone the object has already been answered here.

Lodash reject get return object

var obj = {a: [], b: [1,2], c: [], d: [1]};
How do I get a non-empty array of objects like the following:
{b: [1,2], d: [1]}
You can do what you are after, using pickBy().
var result = _.pickBy(obj, function(val){
return val.length > 0;
});
Fiddle here: https://jsfiddle.net/W4QfJ/3160/
Note: Unlike filter() and reject(), this returns an object, keeping your original structure (rather than an array).
Another way to do this: _.omitBy(obj, _.isEmpty);
_.filter() is what you're looking for:
var obj = {a: [], b: [1,2], c: [], d: [1]};
console.log(_.filter(obj, function(o){ return o.length; }))
If you want to use _.reject() like in your title, you can do something like this:
_.reject({a: [], b: [1,2], c: [], d: [1]},function(o){
return o.length == 0
});
Right now, Lodash has a method called _.omit that does exactly what you need:
> const object = {a: 1, b: 2, c: 3, d: 4}
undefined
> _.omit(object, ['a', 'c'])
{ b: 2, d: 4 }

JavaScript extend array

I have an array of objects. During the loop I append different properties to each entry.
My question - how do I make sure every entry has all the properties of each entry?
Let's consider this:
var myArray = [{A: 1}, {B: 2}, {C: 3}];
Now I want to run some elegant one-liner to convert this array into:
[{A: 1, B:2, C: 3}, {A: 1, B:2, C: 3}, {A: 1, B:2, C: 3}]
An elegant one-liner is a bit difficult without a library. But if you have some kind of extend function, then it could be:
myArray.map(function(v) { return extend.apply(null, [{}].concat(myArray)); });
The extend function would require several objects (passed as separate arguments) to be combined. Such a function is available in jQuery as jQuery.extend, and underscore.js also has one.

Categories