Hi Graydon,
The solutions look similar indeed. Here is an more verbose writing, I hope it's helpful?
map:merge( (: select distinct keys :) for $key in distinct-values( for $map in $maps return map:keys($map) ) (: create new map entry with all values :) return map { $key : for $map in $maps return $map($key) } )
I recommend you to have a closer look at our Wiki article on XQuery 3.1 [1] and, possibly, XQuery 3.0 [2]. We tried to summarize the new language features in a simple and concise manner.
Cheers, Christian
[1] http://docs.basex.org/wiki/XQuery_3.1 [2] http://docs.basex.org/wiki/XQuery_3.0
return map:merge( for $k in distinct-values($maps!map:keys(.)) return map:entry($k, $maps?($k)) )
Your version looks like: map:merge( for $key in distinct-values($maps ! map:keys(.)) return map { $key: ($maps ! .($key)) } )
I feel like I ought to update the docs with one or both but I don't understand the syntax in the return statement of either!
Any chance of getting either or both expanded for the easily-bewildered?
On Sat, Jul 18, 2015 at 8:19 AM, Christian Grün christian.gruen@gmail.com wrote:
Are these easy enough that a map:union() function operating on a sequence of maps isn't something to ask for in the next spec iteration?
Maybe yes. Feel free to propose it on the W3 issue tracker [1]. The talk@x-query.com mailing list may be another place to discuss this.
Best, Christian
[1] https://www.w3.org/Bugs/Public/describecomponents.cgi?product=XPath%20%2F%20...
On Fri, Jul 17, 2015 at 4:18 AM, Christian Grün christian.gruen@gmail.com wrote:
Hi Graydon,
here is one more aproach for (it's not so flexible as the functional approach, though):
declare function local:merge($maps as map(*)*) as map(*) { map:merge( for $key in distinct-values($maps ! map:keys(.)) return map { $key: ($maps ! .($key)) } ) };
local:merge(( map { 'A': 1, 'B': 2 }, map { 'A': 3, 'C': 4 } ))
Cheers, Christian
On Wed, Jul 15, 2015 at 8:01 PM, Graydon Saunders graydonish@gmail.com wrote:
Hi --
In BaseX 8.2.1, I have a bunch of maps; the maps may have some overlap of key values. I would like to merge/find the union of all of these maps while retaining all the values associated with each key in the resulting map-of-all-maps. (Combined map? Any word can be wrong, here! :)
map:merge() doesn't do this; http://docs.basex.org/wiki/Map_Module#map:merge says "The associated value for each such key is taken from the last map in the input sequence $input that contains an entry with this key." and testing confirms this.
Is there a straightforward way to do this that I'm missing?
Thanks! Graydon