325

I once used Lodash _.pluck...I loved pluck...

Realizing Lodash no longer supports pluck (as of Lodash 4.x), I'm struggling to remember what to use instead...

I went to the docs, hit cmd-f, typed 'pluck', but my poor abandoned friend is not even given a proper mention...not even a 'has been replaced by'...

Can someone please remind me what I'm supposed to use instead?

sfletche
  • 47,248
  • 30
  • 103
  • 119

6 Answers6

508

Ah-ha! The Lodash Changelog says it all...

"Removed _.pluck in favor of _.map with iteratee shorthand"

var objects = [{ 'a': 1 }, { 'a': 2 }];

// in 3.10.1
_.pluck(objects, 'a'); // → [1, 2]
_.map(objects, 'a'); // → [1, 2]

// in 4.0.0
_.map(objects, 'a'); // → [1, 2]
sfletche
  • 47,248
  • 30
  • 103
  • 119
  • 122
    Could they not simply keep both...? I don't see the need to rename things just for the sake of renaming them. – Kenny Worden Jun 21 '16 at 18:06
  • 18
    It's not "renaming" though - map already existed - and pluck was simply removed. Map just happens to provide similar functionality with the same argument signature. – Chris Aug 04 '16 at 06:39
  • Are there docs for the iteratee shorthand? I can't see it in the [`_.map` docs](https://lodash.com/docs#map). – Wilfred Hughes Aug 17 '16 at 18:52
  • 1
    @WilfredHughes check out the `_.property` iteree shorthand section of the examples in the [api docs](https://lodash.com/docs#map) – sfletche Aug 17 '16 at 19:47
  • I don't see a problem with leaving `pluck()` in the code base--it is more semantic. – CommandZ Oct 22 '16 at 17:44
  • 2
    Yeah, no need to remove it! They should have just map pluck to return map! (Pun intended) – Arnaldo Capo Oct 31 '16 at 20:13
  • 61
    Why the hell would I want two doorbells on my house? If they both do the same thing, spare people the confusion and get rid of one. In my opinion, this is worth the breaking change. Get rid of extra junk, simplify the API, and people can learn to use the other doorbell. It's not like it's any harder to use. I wish more developers would remove cruft. +1 to the lodash team for introducing the breaking change (no sarcasm here, really). – Landon Poch Nov 06 '16 at 05:53
  • 3
    @LandonPoch, It's more like, you have to rewire your entire house because your doorbell stopped working and needs to be replaced. Deprecated functionality should be phased out. Notice that `_.each` still works in spite of the move to `_.forEach` – eggmatters May 22 '17 at 18:10
  • 32
    Removing pluck just for funzies means nobody can ever safely update lodash. It's not like this is a compiled language... So annoying... – Scott Stafford Jun 16 '17 at 21:20
  • 10
    @ScottStafford That's why it's called a _breaking_ change. If you don't bother reading the changelog when major versions change, then don't bother updating major versions. You can safely update within the same major version. – oligofren Sep 25 '17 at 15:05
  • 6
    @oligofren Now apply that principal in practice: you have 200k lines of javascript code that use 3.x lodash. You can't stay on 3.x forever: suggestions/help/new libraries start using 4.x syntax. New people come on and just look at the newest docs and get stuck, unaware and not caring about 3.x vs 4.x. But you're faced with this: https://github.com/lodash/lodash/wiki/Changelog. What do you do? How do you turn that changelog into the (probably large?) list of actions you must take? So I get breaking changes, but NO MORE THAN NEEDED! And this was not needed. At all. – Scott Stafford Sep 25 '17 at 15:10
  • 3
    @ScottStafford It's very easy; you *don't* look at the entire list. You look at _one single entry_: the 4.0.0 version. That is the single breaking version from 3.x. I found the removed methods after 5 seconds of browsing. All libraries work in this fashion. If you upgrade major versions, breaking API incompatibilities are **expected**. – oligofren Sep 25 '17 at 15:26
  • 2
    @oligofren Ok. The "compatibility warnings" section of v4.0.0 is four feet long. So even though you can find removed methods so impressively fast, I think it'd even take you a while to act on all four feet of changes to assess and then implement any needed changes in a large legacy codebase. Now, what is the upside that makes this worth it? What's wrong with `_.pluck`? – Scott Stafford Sep 25 '17 at 15:34
  • 3
    @ScottStafford so...keep everything forever in every library? I really don't understand what you expect. Development must move forward and developers need to remove unnecessary code or they have to maintain it. The lodash team decided, rightfully, that it wasn't worth the time maintaining two nearly identical functions. – theflowersoftime Sep 25 '17 at 20:32
  • 5
    Just get rid of this with `_.pluck = _.map;`. It's ridiculous they break compatibility not to include an alias like that. 16 characters (-12 bzipped). – Francesco Pasa Nov 30 '17 at 22:37
  • 4
    I also think semantically it made more sense to name this function 'pluck' when used in this context. Typically, in the languages I've experience with, you'd use a map function to perform an operation on each element in a given array. However, pluck (for example the Laravel Collection method) is used to, you got it, pluck elements from a nested array. – thephpdev Dec 14 '17 at 16:21
  • You could create a `_.mixin` for this if you wanted to be a little bit more clear about what you are doing – james2doyle May 16 '18 at 22:25
  • @Chris you do understand the whole point of lodash is compatibility with underscore at a lower filesize, right? – Montagist May 29 '18 at 08:53
  • @Montagist I don't know what that has to do with my comment? Also, I believed it started that way, but diverged many years ago – Chris May 29 '18 at 10:35
  • 3
    Always need to come back to this thread every time I need pluck because I can never remember the name of the "iteratee shorthand" :) – Vadorequest Sep 23 '18 at 00:03
  • 1
    My issue with this is that it's really obscure and hard to look up. I regularly look through the lodash documentation to find functionality by looking at the methods available and researching ones I don't recognize. How am I supposed to recognize this functionality by looking at the method list? In fact the only way I found this out was that I had to go to google to come to this stack overflow answer. That's way too many steps for something that would have been more self explanatory with the name pluck in the first place. – TimE Nov 17 '18 at 19:51
  • 1
    What's even more annoying about breaking API changes: Consider using some 3rd party module whose author uses said API and (for whatever reason) would not reflect the breaking changes in his own code. Sure, a developer can handle that herself, but i would rather avoid tinkering with a codebase my team has no stake in - in any case it's time/effort wasted. Imho, breaking changes are ok if they are mandated by design/implementation changes elsewhere in the code base. They are not ok just to clean up the API, to dedup code or to follow naming conventions. – collapsar Mar 12 '19 at 12:16
  • 5
    C'mon... it's so easy to find/replace `_.pluck` with `_.map` – Luis Lobo Borobia Jul 18 '19 at 23:15
88

There isn't a need for _.map or _.pluck since ES6 has taken off.

Here's an alternative using ES6 JavaScript:

clips.map(clip => clip.id)

Michael J. Calkins
  • 32,082
  • 15
  • 62
  • 91
  • 3
    No need for ES6 even: `Array.prototype.map` is in the ES5.1 standard. See [browser support](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/map#Browser_compatibility) - it goes back as far as anyone needs to worry about in 2017, most probably! – davnicwil Feb 21 '17 at 12:31
  • 2
    @davnicwil `Array.prototype.map` is ES5.1, sure, but the cute arrow syntax `=>` for anonymous functions isn't. ;) – 00dani Feb 23 '17 at 22:53
  • 3
    @00Dani good point! My eyes completely skipped over the fat arrow. Ah well,`clips.map(function (clip) { return clip.id })` still isn't so bad I guess ;-) – davnicwil Feb 24 '17 at 08:55
  • 13
    You can actually make it shorter if using ES6 `clips.map(({id}) => id)` – Dr.Pil Jul 04 '17 at 09:22
  • 1
    This is very true but it's useful to know what happened with `_.pluck` as some pre ES6 projects might make use of lodashe's methods. :) – csalmeida Nov 27 '17 at 12:50
21

Use _.map instead of _.pluck. In the latest version the _.pluck has been removed.

Blue
  • 22,608
  • 7
  • 62
  • 92
4

If you really want _.pluck support back, you can use a mixin:

const _ = require("lodash")

_.mixin({
    pluck: _.map
})

Because map now supports a string (the "iterator") as an argument instead of a function.

Brian Underwood
  • 10,746
  • 1
  • 22
  • 34
Richie Bendall
  • 7,738
  • 4
  • 38
  • 58
0

For plucking single or multiple properties:

_.mixin({
    properties: (paths) =>
            (obj) => paths.reduce((memo, path) => [...memo, obj[path]], []),
    pluck: (obj, ...keys) => _.map(obj, _.flatten(keys).length > 1
                                    ? _.properties(_.flatten(keys))
                                    : (o) => o[keys[0]])
})
var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}];

// underscore compatible usage
_.pluck(stooges, 'name');
=> ["moe", "larry", "curly"]

// multiple property usage
_.pluck(stooges, 'name', 'age')
=> [["moe",40], ["larry",50], ["curly",60]]

// alternate usage
_.pluck(stooges, ['name', 'age']) 
=> [["moe",40], ["larry",50], ["curly",60]]
Orwellophile
  • 13,235
  • 3
  • 69
  • 45
-2

Or try pure ES6 nonlodash method like this

const reducer = (array, object) => {
  array.push(object.a)
  return array
}

var objects = [{ 'a': 1 }, { 'a': 2 }];
objects.reduce(reducer, [])
PayteR
  • 1,727
  • 1
  • 19
  • 35