[proposal] Object.pick
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
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
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.
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
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
@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
@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
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