Assume...
let A = [{ x:'x', y:'y' }, { x:'x', y:'y' }];
I know I can transform this array into a new one taking and renaming the y
property like this...
A.map(o => ({ v: o.y }));
// [{ v:'y' }, { v:'y' }]
And I can use a spread to get all existing properties plus a new, transformed one like this...
A.map(o => ({ ...o, ...{ v: o.y } }));
// [{ x:'x', y:'y', v:'y' }, { x:'x', y:'y', v:'y' }]
But I'm wondering if there's an elegant way to simply rename the y
property to v
. So here's what I want.
// [{ x:'x', v:'y' }, { x:'x', v:'y' }]
I know I can use a function block on my fat arrow function, add a v
property, and delete the y
property, but that's cumbersome. I'm looking for something elegant.
Assume...
let A = [{ x:'x', y:'y' }, { x:'x', y:'y' }];
I know I can transform this array into a new one taking and renaming the y
property like this...
A.map(o => ({ v: o.y }));
// [{ v:'y' }, { v:'y' }]
And I can use a spread to get all existing properties plus a new, transformed one like this...
A.map(o => ({ ...o, ...{ v: o.y } }));
// [{ x:'x', y:'y', v:'y' }, { x:'x', y:'y', v:'y' }]
But I'm wondering if there's an elegant way to simply rename the y
property to v
. So here's what I want.
// [{ x:'x', v:'y' }, { x:'x', v:'y' }]
I know I can use a function block on my fat arrow function, add a v
property, and delete the y
property, but that's cumbersome. I'm looking for something elegant.
- 3 How do you quantify "elegant"? – Taplar Commented Nov 1, 2018 at 20:04
- 1 You tagged the question with ecmascript-6. Please note that "spread properties" are not part of ES6. – Felix Kling Commented Nov 1, 2018 at 22:27
- 1 elegant = you know it when you see it ;) – Jeremy Foster Commented Nov 3, 2018 at 18:29
4 Answers
Reset to default 6You can use Array.map() and Object destructing :
let A = [{ x:'x', y:'y' }, { x:'x', y:'y' }];
let result = A.map(({y,...rest})=> ({...rest,v:y}));
console.log(result);
You could rename the property and use the rest syntax for an object to get all other properties. For mapping take the rested parameters and the new property.
let A = [{ x: 'x', y: 'y' }, { x: 'x', y: 'y' }];
console.log(A.map(({ y: v, ...o }) => ({ ...o, v })));
I know you said you knew you could delete
, but it doesn't necessarily have to be inelegant if you're looking to alter the objects in place:
let A = [{ x:'x', y:'y' }, { x:'x', y:'y' }];
A.forEach(o => delete Object.assign(o, {v: o.y }).y)
console.log(A)
This approach provides a less hard-coded way to convert keys into new ones. On the other hand, this [mapping[k]]
is called Computed property names
.
Likewise, the function Array.prototype.reduce
is building the desired object according to the mapping
and the specific object itself.
Important: The function Array.prototype.map
is creating a new Array, basically is not modifying/mutating the original array.
let A = [{ x:'x', y:'y' }, { x:'x', y:'y' }];
mapping = {'y': 'v'},
result = A.map(o => Object.keys(o).reduce((a, k) => {
if (k in mapping) return Object.assign(a, {[mapping[k]]: o[k]});
return Object.assign(a, {[k]: o[k]});
}, Object.create(null)));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }