最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Elegant way to transform certain property names in an array map - Stack Overflow

programmeradmin1浏览0评论

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.

Share Improve this question asked Nov 1, 2018 at 20:03 Jeremy FosterJeremy Foster 4,7733 gold badges32 silver badges49 bronze badges 3
  • 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
Add a ment  | 

4 Answers 4

Reset to default 6

You 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; }

发布评论

评论列表(0)

  1. 暂无评论