documentcloud/underscore — Issue #436: recommend "flatmap"
Author: rebcabin
Created: 2012-01-15 23:43:58+00:00
State: open

to correspond to Haskell's "bind" and LINQ's "SelectMany." This is a fundamental operator that, in one call, applies a transformation to each element of its input collection -- a transformation that produces a collection of a second kind; and then flattens the result exactly one level. Without it, there is no primitive way to expand a collection ("map" lets you transform a collection, "filter" lets you reduce a collection, and "fold" lets you burn down a collection to a result; but "flatmap" is the fundamental one that lets you build up a collection from elementary inputs. It's fundamental in the monadic sense: it makes your collections into a proper monad with all the pursuant composability benefits.

Canonical example, from a list of customers, each of which has 0 or more orders, each of which has zero or more line-items, extract the list of all orders, preserving the underlying line-item structure but giving up the customer info. Compositionally (in another 'dotted' operation), product the list of all line-items

In a programming pattern of alternating arrays and objects, "map" and "flatten" will (somewhat accidentally) get the job done because "flatten" doesn't flatten objects, only arrays. However, if the data were modeled with pure arrays, I see no good way to do this (without the secret, second argument of "flatten") because the first flatten would blow out all substructure.

I implemented a proposal for flatmap in a fork of this tree, along with a few unit tests for your consideration. I don't have docco running and I didn't produce a "min" version of the javascript, so it's just the javascript and the (fairly uncomprehensive) unit tests.

https://github.com/rebcabin/underscore/commit/4f90bab75d8f69df8d8d0317354f9f5981e2fedb