-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Missing a map() function for collections #945
Comments
Changed the title to: "Missing a map() function for collections". |
+1, I've had to write this myself more than once already. The main challenge is there's no way to get the right generic type signature on the return type: You want to say something like: ... but that doesn't work. That said it'd be nice to have "map" even if it returns List<Dynamic>. Added Area-Library label. |
sample implementation here of "map" "reduce" and "zip" here: |
Removed Type-Defect label. |
This comment was originally written by mattsh@google.com I've always found both "map" and "reduce" to be somewhat unintuitive names. Let's think carefully here about the names here, there might be better choices. (This is even though I've done many mapreduces. Something like "transform" makes more sense to me.) |
Indeed they're strange names. But perhaps they're well known by this point, that it would be worse to change? Personally I think the JS names are pretty good precedent to follow. Our other higher-order APIs on Collection are also consistent with JS Array. FWIW, C# had an interesting take on this: use names from SQL. So "map" is "Select", "reduce" is "Aggregate", "filter" is "Where". I'm not sure if those names are really better though, or just trying to draw on a different set of preconceptions :) |
Without the ability to determine the result list's type, the situation will rapidly degenerated to all lists being <Dynamic>. You can control the result's type if you use a constructor to generate the list: interface List<E> ... { ... var capitalizedNames = new List<String>.transformedFrom(names, capitalize); var capitalizedNames = <String>[capitalize(name) for name in names]; |
Hmm. This actually might be pretty decent? Essentially just adding an optional argument to List.from. I'm not sure how reduce() would fit in though. but +1 to list comprehensions :) |
That's very nice. We could make this work with the existing List.from() just by making it an operational parameter: new List<String>.from(other, map: (e) => e.name); Using a constructor for this also has the advantage of making it clear that it's an eager map and not a lazy one. |
This comment was originally written by @seaneagan Lazy (backed) collections are important too, for composing multiple maps and filters without creating intermediate collections, and so changes to a backing collection can be seen in other collections. I think filter and map should be lazy, since the "from" constructors already handle the eager semantics. One can then compose lazy with eager if desired: List<String> names = other.map<String>((e) => e.name); // issue #254 wanted here // or inline List<String> names = new List.from<String>(other.map<String>((e) => e.name)); |
This comment was originally written by remita...@gmail.com To keep things simple and intuitive, I would like to +1 the original proposal of Collection#map. If we didn't already have Collection#filter, I would take more time to consider the arguments for implementing this as a new List constructor, or by adding an argument to List.from, etc. BUT we already have Collection#filter, which I find to be very simple and intuitive. It's clear from the documentation that #filter eagerly creates and "Returns a new collection with the elements of this collection that satisfy the predicate." Similarly, I think that Dart users would find Collection#map to be clear and simple. Honestly, I think that many Ruby/C#/underscore.js/etc developers will be expecting to have this method on collections, so I argue that we should go ahead and put it there. Regarding the name of the method, I can see how "map" might not be the most intuitive name to some developers, although it's the most popular name for this type of function: http://en.wikipedia.org/wiki/Map_(higher-order_function). "Collect" is another good name for this function, IMHO, which is used in Ruby and Smalltalk. I also like "transform" (from C++) because it's very clear and explicit! But the huge majority of languages seem to use "map." |
Added Fixed label. |
This comment was originally written by @seaneagan Yay, fixed! Is there a CL we can look at ? or was it a spec change for issue #254 ? |
@sethladd is there any example of using map over linkedHashMap. Exception
|
@techyrajeev please file a bug against They simply did not implement it yet. See the code here: https://github.com/google/built_collection.dart/blob/master/lib/src/internal/copy_on_write_map.dart#L57-L63 (Or you can implement it and send them a PR) |
Many libraries and collection libraries have a map() function, allowing the programmer to specify a function which is applied to each element of a collection, collects the return value of the function, and returns a new collection.
In Ruby:
a = [ "a", "b", "c", "d" ]
b = a.map {|x| x + "!" }
b #=> [ "a!", "b!", "c!", "d!" ]
Proposal, for Dart:
var a = ['a', 'b', 'c'];
var b = a.map((x) => x + "!");
b # => ['a!', 'b!', 'c!']
The text was updated successfully, but these errors were encountered: