How to use ES6 destructuring assignment to assign one object to another - javascript

I need the value of keys in object arrA to be copied from arrB based on key name. Here are my two objects:
let arrA = {
'aaa':'',
'bbb':'',
'ccc':''
}
let arrb = {
'aaa':'111',
'bbb':'222',
'ccc':'333',
'ddd':'444',
'eee':'555',
...
}
How do I do this with the ES6 deconstructive assignment:
arrA = {
'aaa':'111',
'bbb':'222',
'ccc':'333'
}

Using destructing assignment, you'd have to explicitly define each property you'd want to copy:
let arra = {
'aaa': '',
'bbb': '',
'ccc': ''
};
let arrb = {
'aaa': '111',
'bbb': '222',
'ccc': '333',
'ddd': '444',
'eee': '555',
};
({aaa: arra.aaa, bbb: arra.bbb, ccc: arra.ccc} = arrb);
console.log(arra);
However, this code is very repetitive, and the worst part is that it's explicit with what gets copied.

The purpose of destructuring is to pull out variables from the object into your local scope. Learn more about destructuring here. You're probably better off solving this problem with different tools.
Using a combination of different functions, you can do this instead:
let arra = {
'aaa':'',
'bbb':'',
'ccc':''
}
let arrb = {
'aaa':'111',
'bbb':'222',
'ccc':'333',
'ddd':'444',
'eee':'555'
}
const result = Object.fromEntries(
Object.keys(arra)
.map(key => [key, arrb[key]])
)
console.log(result)
First, I'm grabbing all of the keys from arra with Object.keys(), then I'm creating a list of pairs using the .map() function, and finally I'm turning the pairs into a new object with Object.fromEntries()

Lodash's pick() is your friend here (because life is too short to write boring boilerpllate code):
You just npm install lodash and say:
const _ = require('lodash');
_.pick( sourceObjectOrArray, arrayOfDesiredPaths );
Like this:
const _ = require('lodash');
const source = {
a: 1,
b: 2,
c: 3,
d: 4,
e: 5,
f: 6,
g: 7,
}
const picked = _.pick( source, ['a','c','e'] );
console.log( JSON.stringify(picked) );
And you'll find picked is what you'd expect:
{
a: 1,
c: 3,
e: 5
}

Related

How to convert an array and an object to enable one-to-one correspondence?

For example I have an Array var array = [1001, 1002, 1003]
And I want to convert this array to an Object like
var obj = {
a: 1001,
b: 1002,
c: 1003
}
I think the easiest way is to do like
obj.a = array[0]
obj.b = array[1]
obj.c = array[2]
However is there have any good ways to do this job and without using for cycle?(because i think if array.length < 5, use obj.x = array[y] will be more efficient?)
And I aslo want to know how to change the obj to a new empty array like?
// first get this obj
var obj = {
a: 1001,
b: 1002,
c: 1003
}
// and then create this new array
var newArray = []
for(let i in obj) {
newArray.push(obj[i])
}
console.log(newArray) // [1001, 1002, 1003]
Does es6 have a good ways to solve this convert from each other ?
You can use Array.prototype.reduce
let array = [1001, 1002, 1003]
let obj = array.reduce((acc, curr, idx) => {
acc[`id${idx + 1}`] = curr;
return acc;
}, {})
console.log(obj)
// if you want the original array back you can use Object.values
console.log(Object.values(obj))
You can use Object.Entries (it is not necessary but it is a cool way and more readable when you want to convert array to object) with Reduce method:
const array = [1001, 1002, 1003];
const result = Object.fromEntries(array.reduce((m,n,i)=>[...m, [`id${++i}`, n]], []));
console.log({array, result});

Destructuring for get the first property of an object?

For arrays, we can define the properties depending on it's indexes like:
const arr = [1, 2, 3];
const [first, second, third] = arr;
console.log(first, second, third)
I'm just wondering if there's a possible solution to do it's reverse with objects like:
const obj = {first: "a", second: "b", third: "c"}
const {0, 1, 2} = obj;
//expected: "a", "b", "c"
You do it like this for objects:
const obj = {foo: 123, bar: 'str'}
const {foo, bar} = obj
It isn't.
Objects are not designed to be ordered, so there isn't a first property per se.
You could convert an object into an array of its values first …
const obj = {
first: "a",
second: "b",
third: "c"
}
const array = Object.values(obj);
const [foo, bar, baz] = array;
console.log({
foo,
bar,
baz
});
… but it is unlikely to be useful and it certainly wouldn't be intuitive code that is easy to maintain.
Try this:
const obj = {first: "a", second: "b", third: "c"}
const indexes = [0, 1, 2]
indexes.map( (val) => { return Object.values(obj)[val] } ) //["a", "b", "c"]
You could take the values and assign this to an array for destructuring.
The order is actually dtermined by the insertation order or if a key is like a valid index of an array, it is sorted numerically to top.
const
object = { first: "a", second: "b", third: "c" },
[first, second, third] = Object.values(object);
console.log(first, second, third);
For extracting a an arbitrary position, you vould take an object with an index an object property assignment pattern [YDKJS: ES6 & Beyond] for a new valid variable.
const
object = { first: "a", second: "b", third: "c" },
{ 2: foo } = Object.values(object);
console.log(foo);

Get same section of two objects in different type

I'd like to find best practice for getting the same section of two objects
const firstObject = { a: 1, b: 2, c: 3}
const secondObject = { 1, 2 }
// desired result: { a: 1, b: 2} or simply { a, b }
In my opinion, we need to do three steps:
1) Get value all values of each object
Object.values = Object.values || (obj => Object.keys(obj).map(key => obj[key]))
2) Find the same section from two arrays value
3) Find key-value pair from firstObject
Any other ways to do it?
Using Standard built-in objects as Array or Object is preferable
Break the firstObject into [key, value] pairs using Object#entries (or polyfill), and use Array#reduce to combine all those that exist in the secondObject.
const firstObject = { a: 1, b: 2, c: 3}
const secondObject = { 1: 1, 2: 2 };
const result = Object.entries(firstObject).reduce((obj, [key, value]) => {
value in secondObject && (obj[key] = value);
return obj;
}, {})
console.log(result);
Object.keys(firstObject).filter(key=> key in secondObject).reduce((o,k)=>(o[k]=firstObject[k],o),{});

javascript merge array of objects, resulting object values in array

Would like to merge an array of objects resulting in an object of unique keys and array of values (duplication of values is ok). Solutions in vanilla JS or lodash preferred.
eg - from this:
[{
a: 1,
b: 2
}, {
a: 1,
c: 3
}]
to this:
{
a: [1, 1],
b: [2],
c: [3]
}
You can use _.mergeWith() with the spread syntax to combine the objects:
const data = [{"a":1,"b":2},{"a":1,"c":3}];
const result = _.mergeWith({}, ...data, (v1 = [], v2) => [...v1, v2]);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
ES6 variant:
const a = [{
a: 1,
b: 2
}, {
a: 1,
c: 3
}]
const b = a.reduce((acc, cur) => Object.assign(acc,
...Object.keys(cur).map(key => ({ [key]: (acc[key] || []).concat(cur[key]) })))
, {})
console.log(b)
without loadash:
var t = [{
a: 1,
b: 2
}, {
a: 1,
c: 3
}];
var result = {};
debugger;
for(var i=0; i<t.length; i++){
for(var j in t[i]){
if(result.hasOwnProperty(j)){
result[j].push(t[i][j]);
}else{
result[j] = [t[i][j]];
}
}
}
console.log(result);
A quick search here in stack reveals that #elclanrs already wrote code for that here However based on the comments, it needs a little tweaking to accept an array of objects, so I added a bit of change to the original code itself.
so basically it boils to the function call:
var merge = function() {
return [].reduce.call(arguments, function(acc, x) {
for(i=0;i<x.length;i++){
Object.keys(x[i]).forEach(function(k) {
acc[k] = (acc[k]||[]).concat([x[i][k]])
});
}
return acc
},{})
}
}
Here's a snippet using the function call (with a bit of small change I put) in that post:
var x = [{a: 1, b: 2}, {a: 1,c: 3}]
var merge = function() {
return [].reduce.call(arguments, function(acc, x) {
for(i=0;i<x.length;i++){
Object.keys(x[i]).forEach(function(k) {
acc[k] = (acc[k]||[]).concat([x[i][k]])
});
}
return acc
},{})
}
y = merge(x);
alert(JSON.stringify(y));
You can use lodash#mergeWith wrapped in a lodash#spread to make lodash#mergeWith treat an array as a list of arguments. We use lodash#concat as a supporting function to concatenate an empty object (to avoid mutating the objects in the collection), the collection, and the customizer function that merges the entire collection. The customizer is composed using lodash#flow, wherein its first argument is lodash#concat that only accepts an arity of 2 using lodash#ary and the second argument uses lodash#compact -- It removes all undefined values in an array.
var result = _.spread(_.mergeWith)(
_.concat({}, data, _.flow(_.ary(_.concat, 2), _.compact))
);
var data = [{
"a": 1,
"b": 2
}, {
"a": 1,
"c": 3
}];
var result = _.spread(_.mergeWith)(
_.concat({}, data, _.flow(_.ary(_.concat, 2), _.compact))
);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

transform object to array with parent child relationship in lodash

Is this possible in lodash or any other javascript/typescript way
var obj = {
a: [ {id:1},{id:2},{id:3}]
b: [ {id:4},{id:5},{id:6}]
c: [ {id:7},{id:8},{id:9}]
}
// transform to
var arr = [
{title:a, items:[{id:1},{id:2},{id:3}]},
{title:b, items: [ {id:4},{id:5},{id:6}]},
{title:c, items: [ id:7},{id:8},{id:9}]}
]
You can use Object.keys for that:
var obj = {
a: [ {id:1},{id:2},{id:3}],
b: [ {id:4},{id:5},{id:6}],
c: [ {id:7},{id:8},{id:9}]
}
var result = Object.keys(obj).map(function(key) {
return { title: key, items: obj[key] }
})
console.log(result);
You can use a highly-readable one-liner for this with lodash and ES6:
_.map(obj, (items, title) => ({ title, items }));
You can completely avoid Object.keys() because map() works on objects. The callback function gets the object key and the value of that key as arguments. So, you can name them in such a way that allows for object literal shorthand notation, as we've done here with items and title.

Categories

Resources