On Tue, May 22, 2012 at 5:57 PM, Herhut, Stephan A < [email protected]> wrote:
> While exploring use cases for data-parallel concurrency in JavaScript > using the ParallelArray API (see > http://wiki.ecmascript.org/doku.php?id=strawman:data_parallelism) I found > myself wanting better support for multiple results from a single parallel > operation. More precisely, I wanted a neat way to do array-of-objects to > object-of-arrays transformations. > > The same problem exists with the Array API, probably to a lesser extent as > one can always fall back to explicit iterators. So, for sake of simplicity, > I will use ordinary Array objects here. Consider the following simple > example: > > function foo (x) { > return {odd: (x%2), twice: 2*x}; > } > > [1,2,3,4].map(foo); > > This will produce an array of objects that have two properties: 'odd' > which encodes whether the corresponding source element was odd and 'twice' > that gives twice the value of the source element. What I typically want, > though, are two arrays containing the odd and twice values, respectively. > For instance, I might want to use 'odd' in a consecutive filter operation > on 'twice'. One way to achieve this is to write a little unzip helper: > > Array.unzip = function unzip(a) { > var r = {}; > for (var e in a) { > for (var k in a[e]) { > (r[k] || (r[k]=[]))[e] = a[e][k]; > } > } > return r; > } > I'm curious about this example implementation, as it won't do what you've illustrated below - I assume you meant to write Array.prototype.unzip? > > which then allows me to conveniently specify the array-of-objects to > object-of-arrays conversion like so: > > result = [1,2,3,4].map(foo).unzip(); > > Throw in destructuring as per > http://wiki.ecmascript.org/doku.php?id=harmony:destructuring, and you get > a pretty workable > > {odd, twice} = [1,2,3,4].map(foo).unzip(); > > Ideally, when implementing this, map should already materialize its result > as two separate arrays if its result is only used by an application of > unzip. A built in unzip with fixed, well known semantics would make this > feasible without the need to analyze what a potential user defined unzip > does. > > Improving on this some more, one could also extend destructuring to > include the required array-of-objects to object-of-arrays transformation > and thus directly allow the programmer to write > > {odd, twice} = [1,2,3,4].map(foo); > > The new semantics of destructuring would have an additional case that, > whenever the rhs is an array like value but the lhs is an object pattern, > the rhs is first transformed into an object of arrays before the pattern is > applied. An implementation is of course free to perform the two steps at > once, allowing for optimizations in cases where only parts of the elements > are selected, as in > > {odd} = [1,2,3,4].map(foo); > > Extending destructuring this way does not impact other cases of > destructuring. Consider the case where the programmer expected an object > but got an array of values. The expression > > {odd, twice} = [1,2,3,4]; > > would still yield odd and twice as undefined. If the lhs is an array > pattern, the extended semantics do not apply at all. > > To summarize, I propose two things. Either, rather conservatively, that an > unzip primitive primitives in JavaScript are limited to Undefined, Null, Boolean, Number, or String per 4.3.2 > be added to Array/ParallelArray or that destructuring be extended such > that if it encounters a lhs object pattern and a rhs evaluating to an array > of objects that it be destructured into objects of arrays corresponding to > variables specified in the lhs. > > Stephan > > _______________________________________________ > es-discuss mailing list > [email protected] > https://mail.mozilla.org/listinfo/es-discuss >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

