[proposal] Object.pick

# Mikkel Davis (23 days ago)

I've seen proposals for syntax additions that give functionality similar to lodash's "pick" utility. But I think it may be more appropriate to add it as an Object utility in the same vein of Object.assign, Object.keys, Object.values. After a quick search, I was surprised to not find an existing proposal like this. Why would that be?

For me, this isn't just one of those "huh, that's a neat lodash util that would be nifty to have natively." The codebase I work on most often already has lodash everywhere, and I have found myself utilizing _.pick frequently, e.g. mapping or passing down portions of React state or props. I really think is common enough that it justifies addition to the spec.

const person = {
    first: 'Marie',
    last: 'Curie',
    age: 51,
    address: 'Grenoble, France',
};

Object.pick(person, ['first', 'age']);  // {first: "Marie", age: 51}

The only other concise way to do this I can think of, using latest ES is (({first, age}) => ({first, age}))(person), which is quite undesirable,

for a variety of reasons.

Another name that might be nice is Object.slice.


Mikkel R. Davis

# Isiah Meadows (23 days ago)

Just as a heads up, this has come up plenty of times before, both as a function and (usually) syntax: www.google.com/search?q=site%3Aesdiscuss.org+pick

I'm good with it being a built-in function, but it's harder to justify using syntax apart from an easier time building up the relevant type ICs.

Isiah Meadows me at isiahmeadows.com, www.isiahmeadows.com

# Mikkel Davis (23 days ago)

Thanks for the heads up! As I mentioned above, I've seen it come up before, but all the top results when searching are syntactic proposals. Syntax would be cool and all, but like you said it may or may not be justified. In the mean time, I don't see any traction for an Object util proposal like this. Does anybody know if this specifically has come up before and if there is a big reason against it?

Mikkel R. Davis

# Jacob Pratt (23 days ago)

Unsure if this is even still being actively weekend out, but I've played around with the binding operator in Babel for this purpose. It definitely has its use case; mine was filtering allowed keys for a REST API.

# T.J. Crowder (23 days ago)

On Wed, Jul 25, 2018 at 10:45 PM, Mikkel Davis <mikkeld at gmail.com> wrote:

I've seen proposals for syntax additions that give functionality similar to lodash's "pick" utility. But I think it may be more appropriate to add it as an Object utility in the same vein of

What I don't like about it being a utility function is the need to create an array of property names or similar. Syntax has its own issues, but I like Bob's proposal: rtm/js-pick-notation

The only other concise way to do this I can think of, using latest ES is (({first, age}) => ({first, age}))(person), which is quite undesirable, for a variety of reasons.

Just FWIW, you can avoid the function there, at the expense of a couple more in-scope identifiers:

const {first, age} = person, result = {first, age};

or to avoid those stray identifiers:

let result;
{
    const {first, age} = person;
    result = {first, age};
}

If/when do expressions:

const result = do {
    const {first, age} = person;
    ({first, age});
};

None of which is pretty either. :-)

-- T.J. Crowder

# Mikkel Davis (22 days ago)

Thank you, TJ. Those are some other interesting options. But undesirable, like you say, least of which because they all require repetition like my snippet in my original post. At least the array of properties avoids the repetition. I agree it's not ideal because of the extra quote marks, but my IDE is still able to follow the logic and point me to where the property/method was included down the line. And really properties are just strings. The quotes would be required anyway with a syntactic solution for properties such as "thing-1", "2thing".

I would love to see a great syntactic solution like the one you mentioned, but as we know it is far more involved to implement those and many do not survive for a variety of reasons. Why not pursue both proposals? We have Array.prototype.concat and array spread, Object.assign and object spread, Boolean(val) and !!val. I realize not all of those are entirely equivalent--my point is that I think there is value in pursing this proposal separate from syntax.

P.S. I haven't used this mailing list before, so I'm not sure why my previous response was all bold. I apologize if this one is, too. I'm just responding via Gmail. No formatting in my response text that I can tell.


Mikkel R. Davis

# Bob Myers (22 days ago)

@Mikkel,

My impression is that one can summarize the attitude of people on this mailing list and those involved in the language design process toward property picking as somewhere between "I don't care enough to worry about it" and "it doesn't belong in the language". To put it a different way, if picking was ever going to get onto the spec track,it already would have. Personally I disagree, but that's a different matter.

That is quite unlikely to change whether picking is implemented in syntax or as some new Object method. I think the latter is actually likely to get even less traction due to the fact that it can be implemented quite trivially in user code and ends up looking quite clunky. Would you really rather write Object.pick(obj, ['a', 'b']) or obj.{a, b}, as one proposal would have it? How does the Object.pick approach provide things like defaults and renaming that are useful when picking and are already in deconstructing syntax which is leveraged directly in the existing syntax-based proposals, where one can say things like obj.{a = 2, b: c}?

Bob

# Mikkel Davis (21 days ago)

@Bob I'm sorry to hear that has been the response here thus far. I'm encouraged, though, to hear there are others like you who see the value in this native ability. I think those are great points about defaults and renaming. The util approach may or may not be able to implement those effectively. Hopefully, we'll see if I or anyone else here can recommend some viable ideas there.

One thing I don't quite follow, though, is the point about a util being easy to implement in user code. The same can be said of Array.prototype.map, String.prototype.startsWith, Object.keys, or Object.assign. The polyfills for each of those are a few lines long. Yes, perhaps I would embrace something like 'a'^str, as a hypothetical example, instead of str.startsWith('a'). Maybe, haha. But imagine if something like that actually makes it into the language some day. Does that mean it was not worth it to include String.prototype.starsWith in the first place?


Mikkel R. Davis