Difference between revisions of "Map Module"

From BaseX Documentation
Jump to navigation Jump to search
m (Text replacement - "</syntaxhighlight>" to "</pre>")
 
(7 intermediate revisions by the same user not shown)
Line 8: Line 8:
  
 
Some examples use the ''map'' {{Code|$week}} defined as:
 
Some examples use the ''map'' {{Code|$week}} defined as:
<syntaxhighlight lang="xquery">
+
<pre lang='xquery'>
 
declare variable $week := map {
 
declare variable $week := map {
 
   0: "Sun", 1: "Mon", 2: "Tue", 3: "Wed", 4: "Thu", 5: "Fri", 6: "Sat"
 
   0: "Sun", 1: "Mon", 2: "Tue", 3: "Wed", 4: "Thu", 5: "Fri", 6: "Sat"
 
};
 
};
</syntaxhighlight>
+
</pre>
  
 
==map:contains==
 
==map:contains==
  
 
{| width='100%'
 
{| width='100%'
| width='120' | '''Signatures'''
+
| width='120' | '''Signature'''
|{{Func|map:contains|$map as map(*), $key as xs:anyAtomicType|xs:boolean}}
+
|<pre>map:contains(
 +
  $map as map(*),
 +
  $key as xs:anyAtomicType
 +
) as xs:boolean</pre>
 
|- valign="top"
 
|- valign="top"
 
| '''Summary'''
 
| '''Summary'''
Line 35: Line 38:
  
 
{| width='100%'
 
{| width='100%'
| width='120' | '''Signatures'''
+
| width='120' | '''Signature'''
|{{Func|map:entry|$key as xs:anyAtomicType, $value as item()*|map(*)}}
+
|<pre>map:entry(
 +
  $key   as xs:anyAtomicType,
 +
  $value as item()*
 +
) as map(*)</pre>
 
|- valign="top"
 
|- valign="top"
 
| '''Summary'''
 
| '''Summary'''
Line 42: Line 48:
 
The function {{Code|map:entry}} is intended primarily for use in conjunction with the function <code>{{Function||map:merge}}</code>. For example, a map containing seven entries may be constructed like this:
 
The function {{Code|map:entry}} is intended primarily for use in conjunction with the function <code>{{Function||map:merge}}</code>. For example, a map containing seven entries may be constructed like this:
  
<syntaxhighlight lang="xquery">
+
<pre lang='xquery'>
 
map:merge((
 
map:merge((
 
   map:entry("Sun", "Sunday"),
 
   map:entry("Sun", "Sunday"),
Line 52: Line 58:
 
   map:entry("Sat", "Saturday")
 
   map:entry("Sat", "Saturday")
 
))
 
))
</syntaxhighlight>
+
</pre>
  
 
Unlike the <code>map { ... }</code> expression, this technique can be used to construct a map with a variable number of entries, for example:
 
Unlike the <code>map { ... }</code> expression, this technique can be used to construct a map with a variable number of entries, for example:
<syntaxhighlight lang="xquery">map:merge(for $b in //book return map:entry($b/isbn, $b))</syntaxhighlight>
+
<pre lang='xquery'>map:merge(for $b in //book return map:entry($b/isbn, $b))</pre>
 
|- valign="top"
 
|- valign="top"
 
| '''Examples'''
 
| '''Examples'''
Line 64: Line 70:
  
 
{| width='100%'
 
{| width='100%'
| width='120' | '''Signatures'''
+
| width='120' | '''Signature'''
|{{Func|map:find|$input as item()*, $key as xs:anyAtomicType|array(*)}}
+
|<pre>map:find(
 +
  $input as item()*,
 +
  $key   as xs:anyAtomicType
 +
) as array(*)</pre>
 
|- valign="top"
 
|- valign="top"
 
| '''Summary'''
 
| '''Summary'''
Line 83: Line 92:
  
 
{| width='100%'
 
{| width='100%'
| width='120' | '''Signatures'''
+
| width='120' | '''Signature'''
|{{Func|map:for-each|$map as map(*), $function as function(xs:anyAtomicType, item()*) as item()*|item()*}}
+
|<pre>map:for-each(
 +
  $map     as map(*),
 +
  $action  as function(xs:anyAtomicType, item()*) as item()*
 +
) as item()*</pre>
 
|- valign="top"
 
|- valign="top"
 
| '''Summary'''
 
| '''Summary'''
|Applies the specified {{Code|$function}} to every key/value pair of the supplied {{Code|$map}} and returns the results as a sequence.
+
|Applies the specified {{Code|$action}} to every key/value pair of the supplied {{Code|$map}} and returns the results as a sequence.
 
|- valign="top"
 
|- valign="top"
 
| '''Examples'''
 
| '''Examples'''
 
|The following query adds the keys and values of all map entries and returns {{Code|(3,7)}}:
 
|The following query adds the keys and values of all map entries and returns {{Code|(3,7)}}:
<syntaxhighlight lang="xquery">
+
<pre lang='xquery'>
 
map:for-each(
 
map:for-each(
 
   map { 1: 2, 3: 4 },
 
   map { 1: 2, 3: 4 },
 
   function($key, $value) { $key + $value }
 
   function($key, $value) { $key + $value }
 
)
 
)
</syntaxhighlight>
+
</pre>
 
|}
 
|}
  
Line 102: Line 114:
  
 
{| width='100%'
 
{| width='100%'
| width='120' | '''Signatures'''
+
| width='120' | '''Signature'''
|{{Func|map:get|$map as map(*), $key as xs:anyAtomicType|item()*}}
+
|<pre>map:get(
 +
  $map as map(*),
 +
  $key as xs:anyAtomicType
 +
) as item()*</pre>
 
|- valign="top"
 
|- valign="top"
 
| '''Summary'''
 
| '''Summary'''
Line 120: Line 135:
  
 
{| width='100%'
 
{| width='100%'
| width='120' | '''Signatures'''
+
| width='120' | '''Signature'''
|{{Func|map:keys|$map as map(*)|xs:anyAtomicType*}}
+
|<pre>map:keys(
 +
  $map as map(*)
 +
) as xs:anyAtomicType*</pre>
 
|- valign="top"
 
|- valign="top"
 
| '''Summary'''
 
| '''Summary'''
Line 134: Line 151:
  
 
{| width='100%'
 
{| width='100%'
| width='120' | '''Signatures'''
+
| width='120' | '''Signature'''
|{{Func|map:merge|$maps as map(*)*|map(*)}}<br/>{{Func|map:merge|$maps as map(*)*, $options as map(*)|map(*)}}<br/>
+
|<pre>map:merge(
 +
  $maps     as map(*)*,
 +
  $options as map(*)   := map { }
 +
) as map(*)</pre>
 
|- valign="top"
 
|- valign="top"
 
| '''Summary'''
 
| '''Summary'''
Line 147: Line 167:
 
* {{Code|map:merge((map:entry(0, "no"), map:entry(1, "yes")))}} creates <code>map { 0: "no", 1: "yes" }</code>.
 
* {{Code|map:merge((map:entry(0, "no"), map:entry(1, "yes")))}} creates <code>map { 0: "no", 1: "yes" }</code>.
 
* The following function adds a seventh entry to an existing map:
 
* The following function adds a seventh entry to an existing map:
<syntaxhighlight lang="xquery">
+
<pre lang='xquery'>
 
map:merge(($week, map { 7: "---" }))
 
map:merge(($week, map { 7: "---" }))
</syntaxhighlight>
+
</pre>
 
* In the following example, the values of all maps are combined, resulting in a map with a single key (<code>map { "key": (1, 2, 3) }</code>):
 
* In the following example, the values of all maps are combined, resulting in a map with a single key (<code>map { "key": (1, 2, 3) }</code>):
<syntaxhighlight lang="xquery">
+
<pre lang='xquery'>
 
map:merge(
 
map:merge(
 
   for $i in 1 to 3 return map { 'key': $i },
 
   for $i in 1 to 3 return map { 'key': $i },
 
   map { 'duplicates': 'combine' }
 
   map { 'duplicates': 'combine' }
 
)
 
)
</syntaxhighlight>
+
</pre>
 
|}
 
|}
  
Line 162: Line 182:
  
 
{| width='100%'
 
{| width='100%'
| width='120' | '''Signatures'''
+
| width='120' | '''Signature'''
|{{Func|map:put|$map as map(*), $key as xs:anyAtomicType, $value as item()*|map(*)}}
+
|<pre>map:put(
 +
  $map   as map(*),
 +
  $key   as xs:anyAtomicType,
 +
  $value as item()*
 +
) as map(*)</pre>
 
|- valign="top"
 
|- valign="top"
 
| '''Summary'''
 
| '''Summary'''
Line 172: Line 196:
  
 
{| width='100%'
 
{| width='100%'
| width='120' | '''Signatures'''
+
| width='120' | '''Signature'''
|{{Func|map:remove|$map as map(*), $keys as xs:anyAtomicType*|map(*)}}<br/>
+
|<pre>map:remove(
 +
  $map   as map(*),
 +
  $keys as xs:anyAtomicType*
 +
) as map(*)</pre>
 
|- valign="top"
 
|- valign="top"
 
| '''Summary'''
 
| '''Summary'''
Line 188: Line 215:
  
 
{| width='100%'
 
{| width='100%'
| width='120' | '''Signatures'''
+
| width='120' | '''Signature'''
|{{Func|map:size|$map as map(*)|xs:integer}}<br/>
+
|<pre>map:size(
 +
  $map as map(*)
 +
) as xs:integer</pre>
 
|- valign="top"
 
|- valign="top"
 
| '''Summary'''
 
| '''Summary'''

Latest revision as of 18:33, 1 December 2023

This XQuery Module contains functions for manipulating maps. Maps have been introduced with XQuery 3.1.

Conventions[edit]

All functions in this module are assigned to the http://www.w3.org/2005/xpath-functions/map namespace, which is statically bound to the map prefix.

Functions[edit]

Some examples use the map $week defined as:

declare variable $week := map {
  0: "Sun", 1: "Mon", 2: "Tue", 3: "Wed", 4: "Thu", 5: "Fri", 6: "Sat"
};

map:contains[edit]

Signature
map:contains(
  $map  as map(*),
  $key  as xs:anyAtomicType
) as xs:boolean
Summary Returns true if the supplied $map contains an entry with a key equal to the supplied value of $key; otherwise it returns false. No error is raised if the map contains keys that are not comparable with the supplied $key.

If the supplied key is xs:untypedAtomic, it is compared as an instance of xs:string. If the supplied key is the xs:float or xs:double value NaN, the function returns true if there is an entry whose key is NaN, or false otherwise.

Examples
  • map:contains($week, 2) returns true().
  • map:contains($week, 9) returns false().
  • map:contains(map {}, "xyz") returns false().
  • map:contains(map { "xyz": 23 }, "xyz") returns true().

map:entry[edit]

Signature
map:entry(
  $key    as xs:anyAtomicType,
  $value  as item()*
) as map(*)
Summary Creates a new map containing a single entry. The key of the entry in the new map is $key, and its associated value is $value.

The function map:entry is intended primarily for use in conjunction with the function map:merge. For example, a map containing seven entries may be constructed like this:

map:merge((
  map:entry("Sun", "Sunday"),
  map:entry("Mon", "Monday"),
  map:entry("Tue", "Tuesday"),
  map:entry("Wed", "Wednesday"),
  map:entry("Thu", "Thursday"),
  map:entry("Fri", "Friday"),
  map:entry("Sat", "Saturday")
))

Unlike the map { ... } expression, this technique can be used to construct a map with a variable number of entries, for example:

map:merge(for $b in //book return map:entry($b/isbn, $b))
Examples map:entry("M", "Monday") creates map { "M": "Monday" }.

map:find[edit]

Signature
map:find(
  $input  as item()*,
  $key    as xs:anyAtomicType
) as array(*)
Summary Returns all values of maps in the supplied $input with the specified $key. The found values will be returned in an array. Arbitrary input will be processed recursively as follows:
  • In a sequence, each item will be processed in order.
  • In an array, all array members will be processed as sequence.
  • In a map, all entries whose keys match the specified key. Moreover, all values of the map will be processed as sequence.
Examples
  • map:find(map { 1:2 }, 1) returns [ 2 ].
  • map:find(map { 1: map { 2: map { 3: 4 } } }, 3) returns [ 4 ].
  • map:find((1, 'b', true#0), 1) returns an empty array.

map:for-each[edit]

Signature
map:for-each(
  $map     as map(*),
  $action  as function(xs:anyAtomicType, item()*) as item()*
) as item()*
Summary Applies the specified $action to every key/value pair of the supplied $map and returns the results as a sequence.
Examples The following query adds the keys and values of all map entries and returns (3,7):
map:for-each(
  map { 1: 2, 3: 4 },
  function($key, $value) { $key + $value }
)

map:get[edit]

Signature
map:get(
  $map  as map(*),
  $key  as xs:anyAtomicType
) as item()*
Summary Returns the value associated with a supplied key in a given map. This function attempts to find an entry within the $map that has a key equal to the supplied value of $key. If there is such an entry, the function returns the associated value; otherwise it returns an empty sequence. No error is raised if the map contains keys that are not comparable with the supplied $key. If the supplied key is xs:untypedAtomic, it is converted to xs:string.

A return value of () from map:get could indicate that the key is present in the map with an associated value of (), or it could indicate that the key is not present in the map. The two cases can be distinguished by calling map:contains. Invoking the map as a function item has the same effect as calling get: that is, when $map is a map, the expression $map($K) is equivalent to get($map, $K). Similarly, the expression get(get(get($map, 'employee'), 'name'), 'first') can be written as $map('employee')('name')('first').

Examples
  • map:get($week, 4) returns "Thu".
  • map:get($week, 9) returns (). (When the key is not present, the function returns an empty sequence.).
  • map:get(map:entry(7,())), 7) returns (). (An empty sequence as the result can also signify that the key is present and the associated value is an empty sequence.).

map:keys[edit]

Signature
map:keys(
  $map  as map(*)
) as xs:anyAtomicType*
Summary Returns a sequence containing all the key values present in a map. The function takes the supplied $map and returns the keys that are present in the map as a sequence of atomic values. The order may differ from the order in which entries were inserted in the map.
Examples
  • map:keys(map { 1: "yes", 2: "no" }) returns (1,2).

map:merge[edit]

Signature
map:merge(
  $maps     as map(*)*,
  $options  as map(*)   := map { }
) as map(*)
Summary Constructs and returns a new map. The map is formed by combining the contents of the supplied $maps. The maps are combined as follows:
  1. There is one entry in the new map for each distinct key present in the union of the input maps.
  2. The $options argument defines how duplicate keys are handled. Currently, a single option duplicates exists, and its allowed values are use-first, use-last, combine and reject (default: use-first).
Examples
  • map:merge(()) creates an empty map.
  • map:merge((map:entry(0, "no"), map:entry(1, "yes"))) creates map { 0: "no", 1: "yes" }.
  • The following function adds a seventh entry to an existing map:
map:merge(($week, map { 7: "---" }))
  • In the following example, the values of all maps are combined, resulting in a map with a single key (map { "key": (1, 2, 3) }):
map:merge(
  for $i in 1 to 3 return map { 'key': $i },
  map { 'duplicates': 'combine' }
)

map:put[edit]

Signature
map:put(
  $map    as map(*),
  $key    as xs:anyAtomicType,
  $value  as item()*
) as map(*)
Summary Creates a new map, containing the entries of the supplied $map and a new entry composed by $key and $value. The semantics of this function are equivalent to map:merge((map { $key, $value }, $map))

map:remove[edit]

Signature
map:remove(
  $map   as map(*),
  $keys  as xs:anyAtomicType*
) as map(*)
Summary Constructs a new map by removing entries from an existing map. The entries in the new map correspond to the entries of $map, excluding entries supplied via $keys.

No failure occurs if the input map contains no entry with the supplied keys; the input map is returned unchanged.

Examples
  • map:remove($week, 4) creates map { 0: "Sun", 1: "Mon", 2: "Tue", 3: "Wed", 5: "Fri", 6: "Sat" }.
  • map:remove($week, 23) creates map { 0: "Sun", 1: "Mon", 2: "Tue", 3: "Wed", 4: "Thu", 5: "Fri", 6: "Sat" }.

map:size[edit]

Signature
map:size(
  $map  as map(*)
) as xs:integer
Summary Returns a the number of entries in the supplied map. The function takes the supplied $map and returns the number of entries that are present in the map.
Examples
  • map:size(map:merge(())) returns 0.
  • map:size(map { "true": 1, "false": 0 }) returns 2.

Changelog[edit]

Version 8.6
  • Added: map:find
  • Updated: map:merge: Signature extended with options argument. By default, value of first key is now adopted (instead of last, as in previous versions).
Version 8.4
  • Removed: map:serialize (use fn:serialize instead)
Version 8.0
  • Added: map:for-each, map:merge, map:put
  • Removed: support for collations (in accordance with the XQuery 3.1 spec).
  • Removed: map:new (replaced with map:merge)
  • Updated: aligned with latest specification: compare keys of type xs:untypedAtomic as xs:string instances, store xs:float or xs:double value NaN.
  • Introduction on maps is now found in the article on XQuery 3.1.
Version 7.8
Version 7.7.1
  • Updated: alternative map syntax without map keyword and : as key/value delimiter (e.g.: { 'key': 'value' })