0

I have an object oldObj that I would like to pick some properties from:

let oldObj = {a: 1, b: 2, c: {d: 3}, d: 100, e: 101}

I want to unpack the properties using the destructuring assignment to create a new object.

let {a, b, c: {d}} = oldObj
let convertedObj = {a,b,d} // {a: 1, b: 2, d: 3}

Is there a way to do this in one line? This would allow for unpacking into a new object without having to write each and every properties twice. E.g something like:

let convertedObj = {...({a,b,c: {d}} = oldObj)} // {a: 1, b: 2, d: 3}

The line above does not work, as the result of running ({a,b,c: {d}} = oldObj) will return the whole oldObj. Hence running ... on that will unpack the whole object in its original form.

JakeTheSnake
  • 2,456
  • 3
  • 14
  • 26
  • 1
    Just FWIW: They're *properties*, not attributes. – T.J. Crowder Nov 09 '22 at 13:06
  • I think using destructoring syntax like this is really abusing it's purpose, when you could just do -> `let _= oldObj; let newObj = {a:_.a, b:_.b, d:_.c.d};` – Keith Nov 09 '22 at 13:10

1 Answers1

3

Is there a way to do this in one line?

There's no fancy way to do it involving destructuring, no. But you don't need it, just a normal object literal does the job. It could be one line or multiple depending on how you want to write it, but is one overall expression (with subexpressions) regardless:

let convertedObj = {a: oldObj.a, b: oldObj.b, d: oldObj.c.d };

let oldObj = { a: 1, b: 2, c: { d: 3 }, d: 100, e: 101 };
let convertedObj = { a: oldObj.a, b: oldObj.b, d: oldObj.c.d };
console.log(convertedObj);

If your starting point is the result of a function call rather than a variable you can repeatedly reference, then either:

  1. Save the function result to a variable and then do the above, or

  2. (What I'd do) Do the destructuring you showed, then build the result.

    const { a, b, c: { d } } = fn();
    let convertedObj = { a, b, d }; // {a: 1, b: 2, d: 3}
    

       
       function fn() {
           return { a: 1, b: 2, c: { d: 3 }, d: 100, e: 101 };
       }
       const { a, b, c: { d } } = fn();
       let convertedObj = { a, b, d }; // {a: 1, b: 2, d: 3}
       console.log(convertedObj);
       
       

But it'll require two overall expressions in that case (unless you want to wrap everything in an arrow function or something like that).

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • I don't think `{a: oldObj.a, ... }` looks very good, especially when property names are long. I figured I could make the code more readable by only having to write out each once. Writing the names once would also allow for the reader to be 100% sure that the property names aren't changed along the way. – JakeTheSnake Nov 09 '22 at 13:23
  • @JakeTheSnake - Fair enough, that's part of why I included my opening sentence. :-) If you don't want to do that, then your destructuring into temporary variables is probably your best approach. That or writing a utility function (or using Lodash's utility function [`pick`](https://lodash.com/docs/4.17.15#pick)). – T.J. Crowder Nov 09 '22 at 13:27