Thanks, Christian. I was able to adapt your second suggestion to my needs as follows:

let $keys := distinct-values(
  for $trial in db:open('CTGov')/clinical_study
  return distinct-values($trial/id_info/org_study_id union $trial/id_info/secondary_id union $trial/acronym)
)

let $map2 := map:merge(
for $key in $keys
let $value :=
for $trial in db:open('CTGov')/clinical_study[id_info/org_study_id = $key or id_info/secondary_id = $key or acronym = $key]
return $trial
return map { $key : $value }
)

The code is fairly efficient, creating the map from 200,000 clinicaltrial.gov trials in about 1 minute.

Any chance this could be made an option of map:merge? Doing it in Java would be faster and more elegant.

Best,
Ron

On December 29, 2015 at 3:12:28 AM, Christian GrĂ¼n (christian.gruen@gmail.com) wrote:

Try this:

let $maps := (
map:entry(0, "red"),
map:entry(1, "green"),
map:entry(1, "blue")
)
return map:merge(
for $map in $maps
for $key in map:keys($map)
group by $key
return map { $key : $map ! .($key) }
)

This is an equivalent, possibly better readable, solution:

let $maps := (
map:entry(0, "red"),
map:entry(1, "green"),
map:entry(1, "blue")
)
let $keys := distinct-values(
for $map in $maps
return map:keys($map)
)
return map:merge(
for $key in $keys
let $value :=
for $map in $maps
return $map($key)
return map { $key : $value }
)


On Wed, Dec 23, 2015 at 11:04 PM, Ron Katriel <rkatriel@mdsol.com> wrote:
> Hi,
>
> I am using map:merge to construct a map from smaller maps and would like to
> preserve values when keys agree. For example, when calling
>
> map:merge((map:entry(0, "red"), (map:entry(1, "green"), map:entry(1,
> "blue")))
>
> I would like to get back something like
>
> map { 0: "red", 1: ("green", "blue") }
>
> The default (W3C) behavior is to drop "green" in favor of "blue".
>
> Is there a simple way to accomplish this? I realize the above example is
> mixing types so presumably a solution would have all values as sets.
>
> Thanks,
> Ron
>