Reputation: 193
I have an array of objects each object has one nested object I need to modify that
Example: What I have below
const array = [{
asset: {key: '1235', type: 'mocFirst'},
id: 27,
marketValuey: 6509,
marketValueySecond: 65033,
marketValueyThird: 650900,
}]
I want get that:
const array = [{
type: 'mocFirst'
key: '1235',
id: 27,
marketValuey: 6509,
marketValueySecond: 65033,
marketValueyThird: 650900,
}]
There is my solution
const array = [{
asset: {key: '1235', type: 'mocFirst'},
id: 27,
marketValuey: 6509,
marketValueySecond: 65033,
marketValueyThird: 650900,
},
{
asset: {key: '12', type: 'mocFirst44'},
id: 27,
marketValuey: 6409,
marketValueySecond: 64033,
marketValueyThird: 640900,
},
{
asset: {key: '1299', type: 'mocFirst'},
id: 271,
marketValuey: 6109,
marketValueySecond: 61033,
marketValueyThird: 610900,
},
{
asset: {key: '1296', type: 'mocFirst'},
id: 272,
marketValuey: 65092,
marketValueySecond: 650332,
marketValueyThird: 6509020,
},
]
const resultArr = array.map(item => {
const { asset, ...newObj} = item;
const { key, type } = item.asset;
return { key, type, ...newObj};
});
Any things about my solution? Maybe it can be done better? In production, I will have a big array
Upvotes: 0
Views: 83
Reputation: 23
I would use a concept of destructuring.
array.map((elem) => {
const {
id,
marketValuey,
marketValueySecond,
marketValueyThird,
asset: {key},
asset: {type}
} = elem;
return {
id,
marketValuey,
marketValueySecond,
marketValueyThird,
key,
type
}
})
for more detailed concept of destructuring refer - nested-destructuring
Upvotes: 1
Reputation: 1062
I like this solution, which I found by searching for "flatten nested object in javascript".
Here is the code in action from my favorite answer:
const crushObj = (obj = {}) => Object.keys(obj || {}).reduce((acc, cur) => {
if (typeof obj[cur] === 'object') {
acc = { ...acc, ...crushObj(obj[cur])}
} else { acc[cur] = obj[cur] }
return acc
}, {})
const obj = {
a:2,
b: {
c:3
}
}
const output = crushObj(obj)
console.log(output)
// { a: 2, c: 3 }
It would be great for a library like Lodash to offer support for this.
Upvotes: 1
Reputation: 5201
If you just need to transform asset.key
and asset.type
respectively into key
and type
, and you want to increase performance, manual assignment of fields is around 4-5 times faster than your solution.
e.g. I have created an array
with 1000 items to compare your solution (which takes around 2.5 ms to create array1
) with mine (around 0.5 ms to create array2
).
const N = 1000;
let array = [];
for (let i = 0; i < N; i++) {
let random_item = {
asset: {
key: Math.random(N),
type: 'mocFirst'
},
id: Math.random(N),
marketValuey: Math.random(N),
marketValueySecond: Math.random(N),
marketValueyThird: Math.random(N)
};
array.push(random_item);
}
const t0 = performance.now();
const array1 = array.map(item => {
const {
asset,
...newObj
} = item;
const {
key,
type
} = item.asset;
return {
key,
type,
...newObj
};
});
console.log(array1[10]);
const t1 = performance.now();
console.log(`Operation took ${t1 - t0} milliseconds.`);
let array2 = [];
for (let i = 0; i < array.length; i++) {
array2.push({
key: array[i].asset.key,
type: array[i].asset.type,
id: array[i].id,
marketValuey: array[i].marketValuey,
marketValueySecond: array[i].marketValueySecond,
marketValueyThird: array[i].marketValueyThird,
});
}
console.log(array2[10]);
const t2 = performance.now();
console.log(`Operation took ${t2 - t1} milliseconds.`);
Upvotes: 1
Reputation: 2732
The only speed-up that you can 'potentially' introduce is via the use of a for loop
instead of a map
method. This does unfortunately depend on how the compiler will optimize your code and the effects will only become noticeable if you are working with very large arrays.
Benchmarking can be referenced here.
The final part of your code should look like this:
const resultArr = [];
for (let i = 0; i < array.length; i += 1) {
const { asset, ...newObj} = array[i];
const { key, type } = asset;
resultArr.push({ key, type, ...newObj});
}
It is important to understand that the speedup of this code will not be very noticeable and developers usually prefer more obvious/maintainable syntax, so your original answer can be considered correct. Hence, use this at your own discretion.
Upvotes: 1
Reputation: 339
Just flatten it out like so:
var outArr = array.map(item => {
// Create the new items
item.key = item.asset.key
item.type = item.asset.item
// Delete the old parent
delete item.asset
return item
})
Upvotes: 1
Reputation: 553
Here you go, it's a recursive solution to flatten the object
function flat(source, target) {
Object.keys(source).forEach(function(k) {
if (source[k] !== null && typeof source[k] === 'object') {
flat(source[k], target);
return;
}
target[k] = source[k];
});
}
const array = [{
asset: {
key: '1235',
type: 'mocFirst'
},
id: 27,
marketValuey: 6509,
marketValueySecond: 65033,
marketValueyThird: 650900,
},
{
asset: {
key: '12',
type: 'mocFirst44'
},
id: 27,
marketValuey: 6409,
marketValueySecond: 64033,
marketValueyThird: 640900,
},
{
asset: {
key: '1299',
type: 'mocFirst'
},
id: 271,
marketValuey: 6109,
marketValueySecond: 61033,
marketValueyThird: 610900,
},
{
asset: {
key: '1296',
type: 'mocFirst'
},
id: 272,
marketValuey: 65092,
marketValueySecond: 650332,
marketValueyThird: 6509020,
},
]
let flatArr = array.map(item => {
let flatObj = {};
flat(item, flatObj);
return flatObj
});
console.log(flatArr);
Upvotes: 4