Difference between revisions of "Map Module"
(Remove outdated sentence about NaNs in map:get() description) |
m (Text replacement - "</syntaxhighlight>" to "</pre>") |
||
(38 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | This [[Module Library|XQuery Module]] contains functions for manipulating maps | + | This [[Module Library|XQuery Module]] contains functions for manipulating maps. [[XQuery 3.1#Maps|Maps]] have been introduced with [[XQuery 3.1]]. |
− | |||
=Conventions= | =Conventions= | ||
Line 9: | Line 8: | ||
Some examples use the ''map'' {{Code|$week}} defined as: | Some examples use the ''map'' {{Code|$week}} defined as: | ||
− | <pre | + | <pre lang='xquery'> |
− | declare variable $week | + | declare variable $week := map { |
− | 0: " | + | 0: "Sun", 1: "Mon", 2: "Tue", 3: "Wed", 4: "Thu", 5: "Fri", 6: "Sat" |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
}; | }; | ||
</pre> | </pre> | ||
==map:contains== | ==map:contains== | ||
+ | |||
{| width='100%' | {| width='100%' | ||
− | | width='120' | ''' | + | | width='120' | '''Signature''' |
− | | | + | |<pre>map:contains( |
− | |- | + | $map as map(*), |
+ | $key as xs:anyAtomicType | ||
+ | ) as xs:boolean</pre> | ||
+ | |- valign="top" | ||
| '''Summary''' | | '''Summary''' | ||
− | | Returns true if the | + | | Returns true if the supplied {{Code|$map}} contains an entry with a key equal to the supplied value of {{Code|$key}}; otherwise it returns false. No error is raised if the map contains keys that are not comparable with the supplied {{Code|$key}}. |
If the supplied key is {{Code|xs:untypedAtomic}}, it is compared as an instance of {{Code|xs:string}}. If the supplied key is the {{Code|xs:float}} or {{Code|xs:double}} value {{Code|NaN}}, the function returns true if there is an entry whose key is {{Code|NaN}}, or false otherwise. | If the supplied key is {{Code|xs:untypedAtomic}}, it is compared as an instance of {{Code|xs:string}}. If the supplied key is the {{Code|xs:float}} or {{Code|xs:double}} value {{Code|NaN}}, the function returns true if there is an entry whose key is {{Code|NaN}}, or false otherwise. | ||
− | |- | + | |- valign="top" |
| '''Examples''' | | '''Examples''' | ||
| | | | ||
Line 39: | Line 36: | ||
==map:entry== | ==map:entry== | ||
+ | |||
{| width='100%' | {| width='100%' | ||
− | | width='120' | ''' | + | | width='120' | '''Signature''' |
− | | | + | |<pre>map:entry( |
− | |- | + | $key as xs:anyAtomicType, |
+ | $value as item()* | ||
+ | ) as map(*)</pre> | ||
+ | |- valign="top" | ||
| '''Summary''' | | '''Summary''' | ||
| Creates a new ''map'' containing a single entry. The key of the entry in the new map is {{Code|$key}}, and its associated value is {{Code|$value}}. | | Creates a new ''map'' containing a single entry. The key of the entry in the new map is {{Code|$key}}, and its associated value is {{Code|$value}}. | ||
− | The function {{Code|map:entry}} is intended primarily for use in conjunction with the function <code> | + | 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: |
− | <pre | + | <pre lang='xquery'> |
map:merge(( | map:merge(( | ||
− | map:entry(" | + | map:entry("Sun", "Sunday"), |
− | map:entry(" | + | map:entry("Mon", "Monday"), |
− | map:entry(" | + | map:entry("Tue", "Tuesday"), |
− | map:entry(" | + | map:entry("Wed", "Wednesday"), |
− | map:entry(" | + | map:entry("Thu", "Thursday"), |
− | map:entry(" | + | map:entry("Fri", "Friday"), |
− | map:entry(" | + | map:entry("Sat", "Saturday") |
)) | )) | ||
</pre> | </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: | ||
− | <pre | + | <pre lang='xquery'>map:merge(for $b in //book return map:entry($b/isbn, $b))</pre> |
− | |- | + | |- valign="top" |
| '''Examples''' | | '''Examples''' | ||
|{{Code|map:entry("M", "Monday")}} creates <code>map { "M": "Monday" }</code>. | |{{Code|map:entry("M", "Monday")}} creates <code>map { "M": "Monday" }</code>. | ||
+ | |} | ||
+ | |||
+ | ==map:find== | ||
+ | |||
+ | {| width='100%' | ||
+ | | width='120' | '''Signature''' | ||
+ | |<pre>map:find( | ||
+ | $input as item()*, | ||
+ | $key as xs:anyAtomicType | ||
+ | ) as array(*)</pre> | ||
+ | |- valign="top" | ||
+ | | '''Summary''' | ||
+ | | Returns all values of maps in the supplied {{Code|$input}} with the specified {{Code|$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. | ||
+ | |- valign="top" | ||
+ | | '''Examples''' | ||
+ | | | ||
+ | * <code>map:find(map { 1:2 }, 1)</code> returns <code>[ 2 ]</code>. | ||
+ | * <code>map:find(map { 1: map { 2: map { 3: 4 } } }, 3)</code> returns <code>[ 4 ]</code>. | ||
+ | * <code>map:find((1, 'b', true#0), 1)</code> returns an empty array. | ||
|} | |} | ||
Line 69: | Line 92: | ||
{| width='100%' | {| width='100%' | ||
− | | width='120' | ''' | + | | width='120' | '''Signature''' |
− | | | + | |<pre>map:for-each( |
− | |- | + | $map as map(*), |
+ | $action as function(xs:anyAtomicType, item()*) as item()* | ||
+ | ) as item()*</pre> | ||
+ | |- valign="top" | ||
| '''Summary''' | | '''Summary''' | ||
− | |Applies | + | |Applies the specified {{Code|$action}} to every key/value pair of the supplied {{Code|$map}} and returns the results as a sequence. |
− | |- | + | |- 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)}}: | ||
− | <pre | + | <pre lang='xquery'> |
map:for-each( | map:for-each( | ||
map { 1: 2, 3: 4 }, | map { 1: 2, 3: 4 }, | ||
− | function($ | + | function($key, $value) { $key + $value } |
) | ) | ||
</pre> | </pre> | ||
Line 86: | Line 112: | ||
==map:get== | ==map:get== | ||
+ | |||
{| width='100%' | {| width='100%' | ||
− | | width='120' | ''' | + | | width='120' | '''Signature''' |
− | | | + | |<pre>map:get( |
− | |- | + | $map as map(*), |
+ | $key as xs:anyAtomicType | ||
+ | ) as item()*</pre> | ||
+ | |- valign="top" | ||
| '''Summary''' | | '''Summary''' | ||
− | |Returns the value associated with a supplied key in a given map. This function attempts to find an entry within the | + | |Returns the value associated with a supplied key in a given map. This function attempts to find an entry within the {{Code|$map}} that has a key equal to the supplied value of {{Code|$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 {{Code|$key}}. If the supplied key is {{Code|xs:untypedAtomic}}, it is converted to {{Code|xs:string}}. |
A return value of {{Code|()}} from {{Code|map:get}} could indicate that the key is present in the map with an associated value of {{Code|()}}, or it could indicate that the key is not present in the map. The two cases can be distinguished by calling {{Code|map:contains}}. | A return value of {{Code|()}} from {{Code|map:get}} could indicate that the key is present in the map with an associated value of {{Code|()}}, or it could indicate that the key is not present in the map. The two cases can be distinguished by calling {{Code|map:contains}}. | ||
− | Invoking the ''map'' as a function item has the same effect as calling {{Code|get}}: that is, when {{Code|$ | + | Invoking the ''map'' as a function item has the same effect as calling {{Code|get}}: that is, when {{Code|$map}} is a map, the expression {{Code|$map($K)}} is equivalent to {{Code|get($map, $K)}}. Similarly, the expression {{Code|get(get(get($map, 'employee'), 'name'), 'first')}} can be written as {{Code|$map('employee')('name')('first')}}. |
− | |- | + | |- valign="top" |
| '''Examples''' | | '''Examples''' | ||
| | | | ||
− | * {{Code|map:get($week, 4)}} returns {{Code|" | + | * {{Code|map:get($week, 4)}} returns {{Code|"Thu"}}. |
* {{Code|map:get($week, 9)}} returns {{Code|()}}. ''(When the key is not present, the function returns an empty sequence.).'' | * {{Code|map:get($week, 9)}} returns {{Code|()}}. ''(When the key is not present, the function returns an empty sequence.).'' | ||
* {{Code|map:get(map:entry(7,())), 7)}} returns {{Code|()}}. ''(An empty sequence as the result can also signify that the key is present and the associated value is an empty sequence.).'' | * {{Code|map:get(map:entry(7,())), 7)}} returns {{Code|()}}. ''(An empty sequence as the result can also signify that the key is present and the associated value is an empty sequence.).'' | ||
Line 103: | Line 133: | ||
==map:keys== | ==map:keys== | ||
+ | |||
{| width='100%' | {| width='100%' | ||
− | | width='120' | ''' | + | | width='120' | '''Signature''' |
− | | | + | |<pre>map:keys( |
− | |- | + | $map as map(*) |
+ | ) as xs:anyAtomicType*</pre> | ||
+ | |- valign="top" | ||
| '''Summary''' | | '''Summary''' | ||
− | |Returns a sequence containing all the key values present in a map. The function takes | + | |Returns a sequence containing all the key values present in a map. The function takes the supplied {{Code|$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. |
− | |- | + | |- valign="top" |
| '''Examples''' | | '''Examples''' | ||
| | | | ||
Line 118: | Line 151: | ||
{| width='100%' | {| width='100%' | ||
− | | width='120' | ''' | + | | width='120' | '''Signature''' |
− | | | + | |<pre>map:merge( |
− | |- | + | $maps as map(*)*, |
+ | $options as map(*) := map { } | ||
+ | ) as map(*)</pre> | ||
+ | |- valign="top" | ||
| '''Summary''' | | '''Summary''' | ||
− | | Constructs and returns a new map. The ''map'' is formed by combining the contents of the | + | | Constructs and returns a new map. The ''map'' is formed by combining the contents of the supplied {{Code|$maps}}. The maps are combined as follows: |
− | + | # There is one entry in the new map for each distinct key present in the union of the input maps. | |
− | # There is one entry in the new map for each distinct key | + | # The {{Code|$options}} argument defines how duplicate keys are handled. Currently, a single option {{Code|duplicates}} exists, and its allowed values are {{Code|use-first}}, {{Code|use-last}}, {{Code|combine}} and {{Code|reject}} (default: {{Code|use-first}}). |
− | + | |- valign="top" | |
− | |||
− | |||
− | |- | ||
| '''Examples''' | | '''Examples''' | ||
| | | | ||
* {{Code|map:merge(())}} creates an empty map. | * {{Code|map:merge(())}} creates an empty map. | ||
* {{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: |
− | + | <pre lang='xquery'> | |
+ | map:merge(($week, map { 7: "---" })) | ||
+ | </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>): | ||
+ | <pre lang='xquery'> | ||
+ | map:merge( | ||
+ | for $i in 1 to 3 return map { 'key': $i }, | ||
+ | map { 'duplicates': 'combine' } | ||
+ | ) | ||
+ | </pre> | ||
|} | |} | ||
Line 140: | Line 182: | ||
{| width='100%' | {| width='100%' | ||
− | | width='120' | ''' | + | | width='120' | '''Signature''' |
− | | | + | |<pre>map:put( |
− | |- | + | $map as map(*), |
+ | $key as xs:anyAtomicType, | ||
+ | $value as item()* | ||
+ | ) as map(*)</pre> | ||
+ | |- valign="top" | ||
| '''Summary''' | | '''Summary''' | ||
− | | Creates a new ''map'', containing the entries of the {{Code|$ | + | | Creates a new ''map'', containing the entries of the supplied {{Code|$map}} and a new entry composed by {{Code|$key}} and {{Code|$value}}. The semantics of this function are equivalent to <code>map:merge((map { $key, $value }, $map))</code> |
|} | |} | ||
==map:remove== | ==map:remove== | ||
+ | |||
{| width='100%' | {| width='100%' | ||
− | | width='120' | ''' | + | | width='120' | '''Signature''' |
− | | | + | |<pre>map:remove( |
− | |- | + | $map as map(*), |
+ | $keys as xs:anyAtomicType* | ||
+ | ) as map(*)</pre> | ||
+ | |- valign="top" | ||
| '''Summary''' | | '''Summary''' | ||
− | | Constructs a new map by removing | + | | Constructs a new map by removing entries from an existing map. The entries in the new map correspond to the entries of {{Code|$map}}, excluding entries supplied via {{Code|$keys}}. |
− | No failure occurs if the input map contains no entry with the supplied | + | No failure occurs if the input map contains no entry with the supplied keys; the input map is returned unchanged. |
− | |- | + | |- valign="top" |
| '''Examples''' | | '''Examples''' | ||
| | | | ||
− | * {{Code|map:remove($week, 4)}} creates <code>map { 0: " | + | * {{Code|map:remove($week, 4)}} creates <code>map { 0: "Sun", 1: "Mon", 2: "Tue", 3: "Wed", 5: "Fri", 6: "Sat" }</code>. |
− | * {{Code|map:remove($week, 23)}} creates <code>map { 0: " | + | * {{Code|map:remove($week, 23)}} creates <code>map { 0: "Sun", 1: "Mon", 2: "Tue", 3: "Wed", 4: "Thu", 5: "Fri", 6: "Sat" }</code>. |
|} | |} | ||
==map:size== | ==map:size== | ||
+ | |||
{| width='100%' | {| width='100%' | ||
− | | width='120' | ''' | + | | width='120' | '''Signature''' |
− | | | + | |<pre>map:size( |
− | |- | + | $map as map(*) |
+ | ) as xs:integer</pre> | ||
+ | |- valign="top" | ||
| '''Summary''' | | '''Summary''' | ||
− | | Returns a the number of entries in the supplied map. The function takes | + | | Returns a the number of entries in the supplied map. The function takes the supplied {{Code|$map}} and returns the number of entries that are present in the map. |
− | |- | + | |- valign="top" |
| '''Examples''' | | '''Examples''' | ||
| | | | ||
Line 176: | Line 229: | ||
|} | |} | ||
− | = | + | =Changelog= |
− | + | ;Version 8.6 | |
− | + | * Added: {{Function||map:find}} | |
− | + | * Updated: {{Function||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 | ;Version 8.0 | ||
− | + | * Added: {{Function||map:for-each}}, {{Function||map:merge}}, {{Function||map:put}} | |
− | * Added: | ||
* Removed: support for collations (in accordance with the XQuery 3.1 spec). | * Removed: support for collations (in accordance with the XQuery 3.1 spec). | ||
* Removed: {{Code|map:new}} (replaced with {{Code|map:merge}}) | * Removed: {{Code|map:new}} (replaced with {{Code|map:merge}}) | ||
Line 203: | Line 246: | ||
;Version 7.8 | ;Version 7.8 | ||
− | |||
* Updated: map syntax <code>map { 'key': 'value' }</code> | * Updated: map syntax <code>map { 'key': 'value' }</code> | ||
− | * Added: | + | * Added: {{Function||map:serialize}} |
;Version 7.7.1 | ;Version 7.7.1 | ||
− | |||
* Updated: alternative map syntax without {{Code|map}} keyword and {{Code|:}} as key/value delimiter (e.g.: <code>{ 'key': 'value' })</code> | * Updated: alternative map syntax without {{Code|map}} keyword and {{Code|:}} as key/value delimiter (e.g.: <code>{ 'key': 'value' })</code> | ||
− | |||
− |
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.
Contents
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 |
Examples |
|
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: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: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:
|
Examples |
|
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 |
Examples |
|
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: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:
|
Examples |
map:merge(($week, map { 7: "---" }))
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: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 |
|
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 withmap:merge
) - Updated: aligned with latest specification: compare keys of type
xs:untypedAtomic
asxs:string
instances, storexs:float
orxs:double
valueNaN
. - Introduction on maps is now found in the article on XQuery 3.1.
- Version 7.8
- Updated: map syntax
map { 'key': 'value' }
- Added:
map:serialize
- Version 7.7.1
- Updated: alternative map syntax without
map
keyword and:
as key/value delimiter (e.g.:{ 'key': 'value' })