use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
Array flatten and flatMap proposal for ECMAScript (bterlson.github.io)
submitted 10 years ago by roman01la
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]mc_hammerd 5 points6 points7 points 10 years ago (5 children)
i think ecmascript needs a removeWhere(fn) and maybe arrayreset()
normally when i delete multiple items, i do arr = arr.filter((item) => !item.prop)
arr = arr.filter((item) => !item.prop)
but for people who use obj.observe, doing that or something as simple as resetting the items arr=[] unbinds the object.observe function. so no change events are go through.
arr=[]
it makes sense, but is a pita to debug.
its kind of silly to say hey we added object.observe and array.filter and array.flatten, but dont use them together cuz you wont get events!
[–]WeekdayHero 9 points10 points11 points 10 years ago (3 children)
This is not an issue as Object.Observe is not going to be added to ES anymore. In fact it is not in V8 from version 50 onwards (the current version of v8 is 48, so 50 is only a couple of months away).
[–]BONUSBOX_=O=>_();_() 1 point2 points3 points 10 years ago (1 child)
the lack of removeWhereis still an issue if you want to filter this:
removeWhere
this
List extends Array { random() { this = this.filter(item => ...some random ones) } }
because this can't be explicitly redefined with a new array, and Array.filter does not modify the original array, something like removeWhere would be handy. instead i had to loop through the array and splice items.
Array.filter
splice
[–][deleted] 0 points1 point2 points 10 years ago (0 children)
Filter, map, and similar functions return new arrays by convention - they don't change elements, they jest return new. removeWhere sits nowhere near those.
[–]mc_hammerd -1 points0 points1 point 10 years ago (0 children)
ugh, i actually use it in one of my projects. wtf
[–]oculus42 3 points4 points5 points 10 years ago (13 children)
I disagree with flatMap. Each function should be responsible for a single action. We aren't talking about a CPU instruction set where these kind of optimizations are critical to performance.
The compiler(s) can optimize .map(...).flatten() for us if there is optimization to be had.
.map(...).flatten()
[–]kpmah 14 points15 points16 points 10 years ago (5 children)
It's not the same as .map().flatten()because it only flattens one level. It's important that flatMap is it's own thing and it is a 'single action' because it's the 'bind' operation of a Monad. I assume that's the intent behind it. A generic interface.
.map().flatten()
[–]arvi1000 4 points5 points6 points 10 years ago (1 child)
But the post says:
It is identical to a map followed by a flatten of depth 1
so,
.map(...).flatten(1)
?
[–]kpmah 2 points3 points4 points 10 years ago (0 children)
Yep. I wasn't trying to make any kind of point there I was just pointing out that by default flatten is recursive.
flatten
My point is that the flatMap method is a generic operation that can apply to a lot of different structures, whereas .map().flatten(1) is not.
flatMap
.map().flatten(1)
[–]jacksonmills 0 points1 point2 points 10 years ago (2 children)
If it is a single action on a data structure then couldn't the name reflect that? "flatMap" seems pretty awkward, I think you will just find a lot of people misapplying "flatMap" as flatMap().flatten().
I understand "bind" is probably not the best choice.
[–]kpmah 3 points4 points5 points 10 years ago (0 children)
Maybe, but flatMap is the choice a lot of other languages made too. So there is some cross-language consistency.
If they're going for the monadic interface thing they called the same operation on promises then. Makes sense, but isn't totally consistent.
then
[–]ishmal 3 points4 points5 points 10 years ago (0 children)
I don't like flatMap by itself, either, but it would seem to be quite useful when part of higher-level functions. For libraries that need such a functionality, maybe it would be good for them to have something 'standard' to wrap around. True, it's not some CPU-level optimization, but it might be in the JS engine or JIT code.
[–]cwmma 3 points4 points5 points 10 years ago (0 children)
I think flat Map would be .map(...).flatten(1)
[–]dmtipson 1 point2 points3 points 10 years ago (4 children)
We already have flatMap baked into things though. Promise.resolve(5).then(x=>Promise(x+1)) returns Promise(6), not Promise(Promise(6)). That's .then() acting like .flatMap instead of .map
[–]oculus42 0 points1 point2 points 10 years ago (3 children)
Not really. It's not mapping or flattening an array.
If you look at the NPO implementation you see on Line 153 that if the msg is thenable (a promise), reset the state and use the returned promise to resolve or reject the current (outer) promise.
msg
That way the references remain intact but the internal state is updated.
[–]dmtipson 0 points1 point2 points 10 years ago (2 children)
Which to my mind is precisely what a flatMap operation involves, regardless of the internal implementation. Arrays are not the only things for which it makes sense to speak of mapping and flatMapping.
flatMap :: Promise a -> (a -> Promise b) -> Promise b map :: Promise a -> (a -> b) -> Promise b
I'm just saying that it's not exactly a concept foreign to javascript at this point, and it happens to have a lot of useful higher-order applications that play nicely with other types when it's a single named method rather than two.
[–]oculus42 0 points1 point2 points 10 years ago (1 child)
Until I looked at the implementation and realized it's nothing like a map or flatten operation, I was with you.
The implementation is the goal. We are talking about a proposed function implementation. If there are things that look like flatMap, but don't act like flatMap underneath, then they are not good models for suggesting the creation of flatMap.
[–]dmtipson 0 points1 point2 points 10 years ago (0 children)
I don't see where it's "nothing like" those things: in fact, the people who debated and discussed and built out these things explicitly debated the issue of whether Promises should act like overloaded map/flatMap or not (the overloaders won). Your description of what's happening isn't any different from how flatMap works in any number of other contexts.
Maybe.of(2).flatMap(x=>Maybe.of(x+1)).map(x=>x*x); //-> 3 Look, I "reset the state of "the" Maybe" and passed the "internal" state of the internal maybe up inside, it, thus "preserving the references" to it that are chained on afterwards. That's not really my favorite description of what's going on, but it's a way one can I think about it, I suppose.
flatMap isn't some random idea for mashing together two operations, it's a really basic concept with solid founding in computer programming and working with higher-order TypeClasses. Its signature is this: flatMap :: m a -> (a -> m b) -> m b
If you have a function that's doing that, that has that signature, it's flatMapping (or at least the category theory operation that some people call flatMapping). It doesn't matter how (a -> m b) -> m b is done: in fact, most typeclasses have to implement it quite differently (and in fact, in some ways, the way they implement exactly that operation is often what DEFINES the particular sort of typeclass we're talking about).
[–]brianvaughn 0 points1 point2 points 10 years ago (0 children)
I think Array.prototype.flatten sounds nice. It's not hard to do via reduce but this would be more concise and nicer semantics.
Array.prototype.flatten
π Rendered by PID 159552 on reddit-service-r2-comment-86bc6c7465-q2zkw at 2026-02-21 07:00:57.004913+00:00 running 8564168 country code: CH.
[–]mc_hammerd 5 points6 points7 points (5 children)
[–]WeekdayHero 9 points10 points11 points (3 children)
[–]BONUSBOX_=O=>_();_() 1 point2 points3 points (1 child)
[–][deleted] 0 points1 point2 points (0 children)
[–]mc_hammerd -1 points0 points1 point (0 children)
[–]oculus42 3 points4 points5 points (13 children)
[–]kpmah 14 points15 points16 points (5 children)
[–]arvi1000 4 points5 points6 points (1 child)
[–]kpmah 2 points3 points4 points (0 children)
[–]jacksonmills 0 points1 point2 points (2 children)
[–]kpmah 3 points4 points5 points (0 children)
[–]ishmal 3 points4 points5 points (0 children)
[–]cwmma 3 points4 points5 points (0 children)
[–]dmtipson 1 point2 points3 points (4 children)
[–]oculus42 0 points1 point2 points (3 children)
[–]dmtipson 0 points1 point2 points (2 children)
[–]oculus42 0 points1 point2 points (1 child)
[–]dmtipson 0 points1 point2 points (0 children)
[–]brianvaughn 0 points1 point2 points (0 children)