Destructuring an object into a new object (like Underscore pick but ESier)

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Destructuring an object into a new object (like Underscore pick but ESier)

Zacqary Adam Xeper

So let's say I have:
let obj = {foo: 1, bar: 2, baz: 3}

And I want to initialize a new object that looks like:
{foo: obj.foo, bar: obj.bar, quux: 4}

I can create a new object with ALL of these properties using a spread operator:
let newObj = {...obj, quux: 4}

But if I want to initialize a new object that pulls in just the foo and bar properties, I have to type this whole structure out:
let newObj = {foo: obj.foo, bar: obj.bar, quux: 4}

Or, if I want to use shorthand property names, I can use a destructuring statement, but then I have to type all the property names twice:
let {foo, bar} = obj;
let newObj = {foo, bar, quux: 4};

Underscore.js has a pick function, which looks like this:
let newObj = {..._(obj).pick(["foo", "bar"]), quux: 4};

but that requires Underscore as a dependency and the syntax is still pretty annoying. I feel like this is a common enough task — especially when trying to avoid mutating data — that there ought to be a native ES way of doing this.

For example, taking a cue from the computed property syntax:
let newObj = { {foo, bar}: obj, quux: 4 }

This also echoes ordinary destructuring syntax, where the variable names are on the left of the equals sign and the object is on the right. Here, it's the same, except for initializing objects.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Destructuring an object into a new object (like Underscore pick but ESier)

Bradley Meck

On Fri, Feb 19, 2016 at 11:32 AM, Zacqary Adam Xeper <[hidden email]> wrote:

So let's say I have:
let obj = {foo: 1, bar: 2, baz: 3}

And I want to initialize a new object that looks like:
{foo: obj.foo, bar: obj.bar, quux: 4}

I can create a new object with ALL of these properties using a spread operator:
let newObj = {...obj, quux: 4}

But if I want to initialize a new object that pulls in just the foo and bar properties, I have to type this whole structure out:
let newObj = {foo: obj.foo, bar: obj.bar, quux: 4}

Or, if I want to use shorthand property names, I can use a destructuring statement, but then I have to type all the property names twice:
let {foo, bar} = obj;
let newObj = {foo, bar, quux: 4};

Underscore.js has a pick function, which looks like this:
let newObj = {..._(obj).pick(["foo", "bar"]), quux: 4};

but that requires Underscore as a dependency and the syntax is still pretty annoying. I feel like this is a common enough task — especially when trying to avoid mutating data — that there ought to be a native ES way of doing this.

For example, taking a cue from the computed property syntax:
let newObj = { {foo, bar}: obj, quux: 4 }

This also echoes ordinary destructuring syntax, where the variable names are on the left of the equals sign and the object is on the right. Here, it's the same, except for initializing objects.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Destructuring an object into a new object (like Underscore pick but ESier)

Bob Myers
In reply to this post by Zacqary Adam Xeper
Indeed, this is the exact objective of the pick notation which I proposed about six months ago, and have now greatly refined and also implemented a proof-of-concept.

In the previous incarnation, I called this a "pick operator" and represented it with `#`, but now I treat it as an extension of dot notation.

What you want is represented as something like

```js
let newObj = obj.{foo, bar};
```

See https://github.com/rtm/js-pick-notation/blob/master/docs/intro.md for a friendly intro. That repo also contains a spec and the POC with tests.

Regards,
Bob Myers

On Fri, Feb 19, 2016 at 11:02 PM, Zacqary Adam Xeper <[hidden email]> wrote:

So let's say I have:
let obj = {foo: 1, bar: 2, baz: 3}

And I want to initialize a new object that looks like:
{foo: obj.foo, bar: obj.bar, quux: 4}

I can create a new object with ALL of these properties using a spread operator:
let newObj = {...obj, quux: 4}

But if I want to initialize a new object that pulls in just the foo and bar properties, I have to type this whole structure out:
let newObj = {foo: obj.foo, bar: obj.bar, quux: 4}

Or, if I want to use shorthand property names, I can use a destructuring statement, but then I have to type all the property names twice:
let {foo, bar} = obj;
let newObj = {foo, bar, quux: 4};

Underscore.js has a pick function, which looks like this:
let newObj = {..._(obj).pick(["foo", "bar"]), quux: 4};

but that requires Underscore as a dependency and the syntax is still pretty annoying. I feel like this is a common enough task — especially when trying to avoid mutating data — that there ought to be a native ES way of doing this.

For example, taking a cue from the computed property syntax:
let newObj = { {foo, bar}: obj, quux: 4 }

This also echoes ordinary destructuring syntax, where the variable names are on the left of the equals sign and the object is on the right. Here, it's the same, except for initializing objects.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Destructuring an object into a new object (like Underscore pick but ESier)

Kevin Smith
In reply to this post by Zacqary Adam Xeper

I can create a new object with ALL of these properties using a spread operator:
let newObj = {...obj, quux: 4}

Let's not do this.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Destructuring an object into a new object (like Underscore pick but ESier)

#!/JoePea
In reply to this post by Bob Myers

Bob, the benefit of your proposed syntax would be that the object identifier comes first instead of last, so the reader can see the intent of the code sooner:

```js
let newObj = {...obj.{foo, bar}, quux:4}
```

/#!/JoePea

On Feb 19, 2016 9:55 AM, "Bob Myers" <[hidden email]> wrote:
Indeed, this is the exact objective of the pick notation which I proposed about six months ago, and have now greatly refined and also implemented a proof-of-concept.

In the previous incarnation, I called this a "pick operator" and represented it with `#`, but now I treat it as an extension of dot notation.

What you want is represented as something like

```js
let newObj = obj.{foo, bar};
```

See https://github.com/rtm/js-pick-notation/blob/master/docs/intro.md for a friendly intro. That repo also contains a spec and the POC with tests.

Regards,
Bob Myers

On Fri, Feb 19, 2016 at 11:02 PM, Zacqary Adam Xeper <[hidden email]> wrote:

So let's say I have:
let obj = {foo: 1, bar: 2, baz: 3}

And I want to initialize a new object that looks like:
{foo: obj.foo, bar: obj.bar, quux: 4}

I can create a new object with ALL of these properties using a spread operator:
let newObj = {...obj, quux: 4}

But if I want to initialize a new object that pulls in just the foo and bar properties, I have to type this whole structure out:
let newObj = {foo: obj.foo, bar: obj.bar, quux: 4}

Or, if I want to use shorthand property names, I can use a destructuring statement, but then I have to type all the property names twice:
let {foo, bar} = obj;
let newObj = {foo, bar, quux: 4};

Underscore.js has a pick function, which looks like this:
let newObj = {..._(obj).pick(["foo", "bar"]), quux: 4};

but that requires Underscore as a dependency and the syntax is still pretty annoying. I feel like this is a common enough task — especially when trying to avoid mutating data — that there ought to be a native ES way of doing this.

For example, taking a cue from the computed property syntax:
let newObj = { {foo, bar}: obj, quux: 4 }

This also echoes ordinary destructuring syntax, where the variable names are on the left of the equals sign and the object is on the right. Here, it's the same, except for initializing objects.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Destructuring an object into a new object (like Underscore pick but ESier)

Zacqary Adam Xeper
In reply to this post by Bob Myers
I like how your pick notation can combine easily with spread operators:

let newObj = { ...obj.{foo, bar}, quux: 4}

I think I actually prefer that to mine. Destructuring on the left side of a colon is sort of fighting against the spread operator, and might suggest a more natural syntax of { {*}: obj } instead of {...obj}. And I don't like that.

On Fri, Feb 19, 2016 at 12:55 PM, Bob Myers <[hidden email]> wrote:
Indeed, this is the exact objective of the pick notation which I proposed about six months ago, and have now greatly refined and also implemented a proof-of-concept.

In the previous incarnation, I called this a "pick operator" and represented it with `#`, but now I treat it as an extension of dot notation.

What you want is represented as something like

```js
let newObj = obj.{foo, bar};
```

See https://github.com/rtm/js-pick-notation/blob/master/docs/intro.md for a friendly intro. That repo also contains a spec and the POC with tests.

Regards,
Bob Myers

On Fri, Feb 19, 2016 at 11:02 PM, Zacqary Adam Xeper <[hidden email]> wrote:

So let's say I have:
let obj = {foo: 1, bar: 2, baz: 3}

And I want to initialize a new object that looks like:
{foo: obj.foo, bar: obj.bar, quux: 4}

I can create a new object with ALL of these properties using a spread operator:
let newObj = {...obj, quux: 4}

But if I want to initialize a new object that pulls in just the foo and bar properties, I have to type this whole structure out:
let newObj = {foo: obj.foo, bar: obj.bar, quux: 4}

Or, if I want to use shorthand property names, I can use a destructuring statement, but then I have to type all the property names twice:
let {foo, bar} = obj;
let newObj = {foo, bar, quux: 4};

Underscore.js has a pick function, which looks like this:
let newObj = {..._(obj).pick(["foo", "bar"]), quux: 4};

but that requires Underscore as a dependency and the syntax is still pretty annoying. I feel like this is a common enough task — especially when trying to avoid mutating data — that there ought to be a native ES way of doing this.

For example, taking a cue from the computed property syntax:
let newObj = { {foo, bar}: obj, quux: 4 }

This also echoes ordinary destructuring syntax, where the variable names are on the left of the equals sign and the object is on the right. Here, it's the same, except for initializing objects.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Destructuring an object into a new object (like Underscore pick but ESier)

Bergi
In reply to this post by Zacqary Adam Xeper
Zacqary Adam Xeper wrote:

> But if I want to initialize a new object that pulls in just the foo and bar
> properties, I have to type this whole structure out:
> let newObj = {foo: obj.foo, bar: obj.bar, quux: 4}
>
> Or, if I want to use shorthand property names, I can use a destructuring
> statement, but then I have to type all the property names twice:
> let {foo, bar} = obj;
> let newObj = {foo, bar, quux: 4};

I would suggest that we also allow property references, not only
variable identifiers in shorthand property notation:

let newObj = {obj.foo, obj.bar, quux: 4};

What do you think?

Regards,
  Bergi
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Destructuring an object into a new object (like Underscore pick but ESier)

Bergi
Viktor Kronvall schrieb:

> What would this do?
> ```
> let newObj = {obj.a.b}
> ```
>
> `{a: {b: obj.a.b}}`
> or
> `{a: obj.a.b}`?
>
> Or should nested property access be disallowed?

Neither - `obj.a.b` is `(obj.a).b`, so it's equivalent to `let newObj =
{b: obj.a.b}`.
The spec would basically be something like

| Let propKey be GetReferencedName(exprValue)

and otherwise [the
same](http://www.ecma-international.org/ecma-262/6.0/#sec-object-initializer-runtime-semantics-propertydefinitionevaluation).
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Destructuring an object into a new object (like Underscore pick but ESier)

Bob Myers
In my proposal, there are two syntaxes related to "deep" or "nested" picking.

Assuming:

```js
var obj = {a: {b: 1, c: 2}, d: 3};
```

Inside the picking construct, the dot does a "deep pick":

```
obj.{a.b} // { b: 1 }
```

The colon does a "nested pick":

```
obj.{a: {b}} // { a: {b: 1}}
```

Bob

On Mon, Feb 22, 2016 at 6:16 AM, Bergi <[hidden email]> wrote:
Viktor Kronvall schrieb:
What would this do?
```
let newObj = {obj.a.b}
```

`{a: {b: obj.a.b}}`
or
`{a: obj.a.b}`?

Or should nested property access be disallowed?


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss