Note that the optional options argument in map:merge can change the way it handles duplicate keys.
I’ve used this to create maps of normalized document ids from two different collections to de-dup,
Where the ids SHOULD be uniq within a collection, but actually aren’t, or are missing. 

https://www.w3.org/TR/xpath-functions-31/#func-map-merge

( Next step was to split the uniq and non-uniq ones to handle separately. ) 

declare variable $OAI := map:merge( for $d in $ORG_OAI 
  return map:entry( local:normalize( local:unitid($d )), $d ), map{'duplicates':'combine'}); 
declare variable $VH := map:merge( for $d in $ORG_VH
  return map:entry( local:normalize( local:unitid($d )), $d ), map{'duplicates':'combine'});


However, after discussion on this list about SQL join equivalents, I discovered I could do something almost equivalent with a for/join, and that full text search tokenization gives me a similar way of normalizing IDs: 


for $VH in collection( $R($ORG)('vh'))/ead/archdesc/did/unitid, 
                $OAI in collection( $R($ORG)('oai'))/ead/archdesc/did/unitid[ . contains text  {string($VH)}]
       order by $VH


I think the map version may be a bit faster, but I haven’t actually measured 
And they are doing things a bit differently, as I’m not removing the internal duplicates,
But using the order by to group multiple matches together to make it visible in the report. 


I would also note that dealing with messy data, often with hidden encoding errors in documents,
Is the reason I was asking in a previous thread about using the result of one script as context 
for other queries. Sometimes this ends up being a rather exploratory process, so that has come
in very handy. 

— Steve M.


On May 25, 2022, at 12:13 PM, Hans-Juergen Rennau <hrennau@yahoo.de> wrote:

Hi Markus,

although I do not quite understand your description (why should I care for the representation of the map I construct?), it may be that one piece of information is useful to you, as it is not obvious from the spec: it's about how to construct a map dynamically, that is, 

(1) when the keys are not known beforehand, 
(2) and/or when the entry values are assigned in "iterations" of a FLWOR expression

(Especially (2) might be what puzzles you.)

(1) and (2) can't be accomplished when using the map constructor expression, like this: basex "map{'x':1, 'y': false()}" 

The trick consists of using a combination of the functions map:merge() [1] and map:entry() [2].

So summarize, the code constructing the map entries is the argument of function map:merge().This code may for example be (most often is) a FLWOR expression. In this code, each entry is constructed by a call of function map:entry(). For a tiny example see below.

Kind regards,
Hans-Jürgen

PS: Tiny example demonstrating the construction of maps via map:merge() & map:entry().

(: Creates a map with one entry for each element name
   encountered in the input document. The entry value
   is the number of elements with that name. As the
   map keys are not known in advance, map:merge() is
   used.
 :)
map:merge(
    for $elem in //*
    group by $name := $elem/local-name(.)
    return map:entry($name, count($elem))
)







Am Mittwoch, 25. Mai 2022, 16:59:48 MESZ hat Markus Elfring <markus.elfring@web.de> Folgendes geschrieben:


Hello,

I would like to construct a map structure based on a dynamic selection by
the means of a FLWOR expression.

The keys and associated values should be presented as a CSV-like file by
a subsequent data processing step.

Can it become easier to find existing XQuery script examples for such an use case?

Regards,
Markus