# Object.{pick,omit}

**URL:** <https://es.discourse.group/t/object-pick-omit/515>\
**Category:** 💡 Ideas\
**Created:** [October 26, 2020, 8:42am UTC](https://es.discourse.group/t/object-pick-omit/515 "2020-10-26T08:42:46Z")\
**Posts on this page:** 20\
**Page:** 3

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [April 6, 2021, 9:45am UTC](https://es.discourse.group/t/object-pick-omit/515/42 "2021-04-06T09:45:11Z")

</div>

Basically, `Object.pick` is enough for developers to extend it as `pickOwn`:

```javascript
const pickOwn = (obj, keys) =>
    Object.pick(obj, keys.filter(obj.hasOwnProperty.bind(obj)));

```

Reversely, if `Object.pick` won't pick up properties from the prototype chain, it is meaningless as it is strict.

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [April 6, 2021, 2:20pm UTC](https://es.discourse.group/t/object-pick-omit/515/43 "2021-04-06T14:20:15Z")

</div>

> [@aleen42](#):
>
> it is meaningless as it is strict.

What do you mean by this phrase?

---

<div class="post-metadata">

**Author:** ![krazov](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/krazov/32/814_2.png) [@krazov](https://es.discourse.group/u/krazov)\
**Post date:** [April 6, 2021, 4:18pm UTC](https://es.discourse.group/t/object-pick-omit/515/44 "2021-04-06T16:18:03Z")

</div>

@senocular and @aleen42, I am convinced. I saw pick and omit as more symmetrical operations to each other, but it makes more sense to not ignore the prototype chain.

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [April 7, 2021, 1:04am UTC](https://es.discourse.group/t/object-pick-omit/515/45 "2021-04-07T01:04:04Z")

</div>

It means that `Object.pick` can not be extended to pick up from the prototype chain any more.

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [April 12, 2021, 8:06am UTC](https://es.discourse.group/t/object-pick-omit/515/46 "2021-04-12T08:06:37Z")

</div>

@ljharb To put this proposal into stage 0, what is the next step can I do? Just wait for a champion to lead?

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [April 12, 2021, 3:47pm UTC](https://es.discourse.group/t/object-pick-omit/515/47 "2021-04-12T15:47:37Z")

</div>

You could start by using [https://github.com/tc39/template-for-proposals](https://github.com/tc39/template-for-proposals) to make a proposal repo. Clearly outlining the problem first and foremost, discussing prior art and userland solutions, discussing current alternatives, and then discussing a proposed solution would go a long way towards convincing a delegate to champion it.

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [April 13, 2021, 3:40am UTC](https://es.discourse.group/t/object-pick-omit/515/48 "2021-04-13T03:40:26Z")

</div>

Thanks. I have created [GitHub - aleen42/proposal-object-pick-or-omit: Introduce `Object.prototype.{pick,omit}` for operating properties of objects more conveniently.](https://github.com/aleen42/proposal-object-pick-or-omit) before and I appreciate anyone's suggestions on it.

---

<div class="post-metadata">

**Author:** ![septs](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/septs/32/395_2.png) [@septs](https://es.discourse.group/u/septs)\
**Post date:** [April 16, 2021, 9:15pm UTC](https://es.discourse.group/t/object-pick-omit/515/49 "2021-04-16T21:15:04Z")

</div>

suggest, update this repo description, now incorrect.

![image](https://global.discourse-cdn.com/free1/uploads/es/original/1X/15c3a837d3b6bd4df3e153891dbda2cd36f23f15.png)

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [April 17, 2021, 2:07am UTC](https://es.discourse.group/t/object-pick-omit/515/50 "2021-04-17T02:07:36Z")

</div>

Already update, thx.

---

<div class="post-metadata">

**Author:** ![jamiebuilds](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/jamiebuilds/32/857_2.png) [@jamiebuilds](https://es.discourse.group/u/jamiebuilds)\
**Post date:** [June 10, 2021, 7:40pm UTC](https://es.discourse.group/t/object-pick-omit/515/51 "2021-06-10T19:40:06Z")

</div>

If you treat pick as a similar problem as array slicing, it makes sense that it would have a dedicated syntax for it similar to this proposal: [GitHub - tc39/proposal-slice-notation](https://github.com/tc39/proposal-slice-notation)

Something like

```javascript
let full = { a: 1, b: 2, c: 3 }
let part = full.{a,b} // { a: 1, b: 2 }

```

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [June 10, 2021, 10:01pm UTC](https://es.discourse.group/t/object-pick-omit/515/52 "2021-06-10T22:01:25Z")

</div>

Though if that's an argument for anything, it's an argument for having both syntax and a built-in function.

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [June 11, 2021, 3:37pm UTC](https://es.discourse.group/t/object-pick-omit/515/53 "2021-06-11T15:37:38Z")

</div>

If I want to slice with a series of dynamic keys, how the statement should be? Like this?

```javascript
full.[object]

```

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [June 11, 2021, 3:47pm UTC](https://es.discourse.group/t/object-pick-omit/515/54 "2021-06-11T15:47:19Z")

</div>

Slice or pick?

If we chose to support picking with dynamic keys, my recommendation would be something like this:

```javascript
let full = { a: 1, b: 2, c: 3, d: 4 }

const key = 'a'
console.log(full.{ [key], d }) // { a: 1, d: 4 }

const keys = ['a', 'b']
console.log(full.{ ...keys, d }) // { a: 1, b: 2, d: 4 }

```

Though I would rather have both a pick() function and a pick syntax, and have the function version support dynamic keys while the syntax version does not. I don't think dynamic keys is a common enough use case for the added syntax baggage.

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [June 11, 2021, 4:13pm UTC](https://es.discourse.group/t/object-pick-omit/515/55 "2021-06-11T16:13:03Z")

</div>

In my opinion, using square brackets (`[]`) may conform to our perception of JavaScript as what we need is a serires of keys to pick from:

```javascript
({a : 1, b : 2, c : 3}).['a', 'b']; // => {a : 1, b : 2}

const keys = ['a', 'b'];
({a : 1, b : 2, c : 3}).[keys[0]]; // => {a : 1}
({a : 1, b : 2, c : 3}).[...keys]; // => {a : 1, b : 2}

```

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [June 11, 2021, 10:09pm UTC](https://es.discourse.group/t/object-pick-omit/515/56 "2021-06-11T22:09:38Z")

</div>

> [@aleen42](#):
>
> In my opinion, using square brackets (`[]`) may conform to our perception of JavaScript as what we need is a serires of keys to pick from:

Unfortunately, that would make `o.[a, b]` very different from `o?.[a, b]` and `o[a, b]`  
(just to be clear I think comma should not be an operator there, but sadly it is).

You could drop the superfluous `.` in-between and just use `...` to distinguish slicing from indexing:

```javascript
({a : 1, b : 2, c : 3})[...['a', 'b']]; // => {a : 1, b : 2}

const keys = ['a', 'b'];
({a : 1, b : 2, c : 3})[...[keys[0]]]; // => {a : 1}
({a : 1, b : 2, c : 3})[...keys]; // => {a : 1, b : 2}

```

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [June 12, 2021, 1:57am UTC](https://es.discourse.group/t/object-pick-omit/515/57 "2021-06-12T01:57:52Z")

</div>

Without the dot notation, it should be confused in such a case:

```javascript
({a : 1, b : 2, c : 3})['a']; // => expect {a : 1} but 1 actually

```

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [June 12, 2021, 2:13am UTC](https://es.discourse.group/t/object-pick-omit/515/58 "2021-06-12T02:13:13Z")

</div>

That "expect" is clearly wrong, nothing confusing about it. I said remove the dot outside and use 3 inside instead. You omitted the dots inside, of course that's plain old indexing.

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [June 12, 2021, 2:54am UTC](https://es.discourse.group/t/object-pick-omit/515/59 "2021-06-12T02:54:49Z")

</div>

Just to clarify, are you two (@lightmare and @aleen42) proposing these bracket syntaxes in addition to the `full.{a, b}` syntax that @jamiebuilds proposed? Or in place of? I presume it's in place of?

I'm going to make a couple of arguments in favor of @jamiebuilds's syntax:

It's built for the most common use case of just picking pre-known properties off of an object. You don't have to use strings (but we can still add support for dynamic key if wanted. Similar to how object literals and destructuring are built for the most common use case of non-dynamic keys, but have support for dynamic keys)

It could be extended to support other nice features, such as renaming while picking the properties off, or setting default values if the properties don't exist. Hopefully, you can see a parallel with object destructuring. With object destructuring, we pick properties off and put them in the local namespace. With this pick syntax, we pick properties off and put them in a new object.

It's actually got a minor prior art in Microsoft's Bosque language as well (see [here](https://github.com/microsoft/BosqueLanguage/blob/c841324bf706b60d8a9dbb1519a8e5227fc5bd9f/docs/language/overview.md#06-bulk-algebraic-data-operations)), which has an object pick syntax that's exactly the same.

(I've actually started a thread in the past which suggested having this kind of syntax [here](https://es.discourse.group/t/object-restructuring-syntax/651), which is why I like it so much)

```javascript
// pick a, b, and c off
// if b doesn't exist, set it to 2
// rename c to C
const newObj = oldObj.{ a, b = 2, c: C }

// Example of dynamic keys
// (again, do you see the parallel with object destructuring?)
const anotherNewObj = something.{ x, [key1], [key2]: renamedKey }

```

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [June 12, 2021, 3:14am UTC](https://es.discourse.group/t/object-pick-omit/515/60 "2021-06-12T03:14:23Z")

</div>

So what should that returns?

```javascript
({a : 1, b : 2, c : 3})[...['a']];

```

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [June 12, 2021, 3:30am UTC](https://es.discourse.group/t/object-pick-omit/515/61 "2021-06-12T03:30:40Z")

</div>

It seems like a shortcut of:

```javascript
const {a, b = 2, c : C} = oldObj;
const newObj = {a, b, C};

```

[Previous page](https://es.discourse.group/t/object-pick-omit/515.md?page=2)

[Next page](https://es.discourse.group/t/object-pick-omit/515.md?page=4)
