Difference between revisions of "Map Module"
(21 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. Maps have been introduced with XQuery 3.1 and are described in detail in the [https://www.w3.org/TR/xpath-functions-31/#maps-and-arrays XQuery Functions and Operators 3.1 specification]. |
− | |||
=Conventions= | =Conventions= | ||
Line 10: | Line 9: | ||
Some examples use the ''map'' {{Code|$week}} defined as: | Some examples use the ''map'' {{Code|$week}} defined as: | ||
<pre class="brush:xquery"> | <pre class="brush: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' | '''Signatures''' | | width='120' | '''Signatures''' | ||
− | |{{Func|map:contains|$ | + | |{{Func|map:contains|$map as map(*), $key as xs:anyAtomicType|xs:boolean}} |
|- | |- | ||
| '''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. | ||
|- | |- | ||
Line 39: | Line 33: | ||
==map:entry== | ==map:entry== | ||
+ | |||
{| width='100%' | {| width='100%' | ||
| width='120' | '''Signatures''' | | width='120' | '''Signatures''' | ||
Line 49: | Line 44: | ||
<pre class="brush:xquery"> | <pre class="brush: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> | ||
Line 64: | Line 59: | ||
| '''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' | '''Signatures''' | ||
+ | |{{Func|map:find|$input as item()*, $key as xs:anyAtomicType|array(*)}} | ||
+ | |- | ||
+ | | '''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. | ||
+ | |- | ||
+ | | '''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 70: | Line 84: | ||
{| width='100%' | {| width='100%' | ||
| width='120' | '''Signatures''' | | width='120' | '''Signatures''' | ||
− | |{{Func|map:for-each|$ | + | |{{Func|map:for-each|$map as map(*), $function as function(xs:anyAtomicType, item()*) as item()*|item()*}} |
|- | |- | ||
| '''Summary''' | | '''Summary''' | ||
− | |Applies | + | |Applies the specified {{Code|$function}} to every key/value pair of the supplied {{Code|$map}} and returns the results as a sequence. |
|- | |- | ||
| '''Examples''' | | '''Examples''' | ||
Line 80: | Line 94: | ||
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 100: | ||
==map:get== | ==map:get== | ||
+ | |||
{| width='100%' | {| width='100%' | ||
| width='120' | '''Signatures''' | | width='120' | '''Signatures''' | ||
− | |{{Func|map:get|$ | + | |{{Func|map:get|$map as map(*), $key as xs:anyAtomicType|item()*}} |
|- | |- | ||
| '''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')}}. |
|- | |- | ||
| '''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 118: | ||
==map:keys== | ==map:keys== | ||
+ | |||
{| width='100%' | {| width='100%' | ||
| width='120' | '''Signatures''' | | width='120' | '''Signatures''' | ||
− | |{{Func|map:keys|$ | + | |{{Func|map:keys|$map as map(*)|xs:anyAtomicType*}} |
|- | |- | ||
| '''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. |
|- | |- | ||
| '''Examples''' | | '''Examples''' | ||
Line 119: | Line 135: | ||
{| width='100%' | {| width='100%' | ||
| width='120' | '''Signatures''' | | width='120' | '''Signatures''' | ||
− | |{{Func|map:merge|$ | + | |{{Func|map:merge|$maps as map(*)*|map(*)}}<br/>{{Func|map:merge|$maps as map(*)*, $options as map(*)|map(*)}}<br/> |
|- | |- | ||
| '''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}}). |
− | |||
− | |||
− | |||
|- | |- | ||
| '''Examples''' | | '''Examples''' | ||
Line 133: | Line 146: | ||
* {{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 class="brush: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 class="brush:xquery"> | ||
+ | map:merge( | ||
+ | for $i in 1 to 3 return map { 'key': $i }, | ||
+ | map { 'duplicates': 'combine' } | ||
+ | ) | ||
+ | </pre> | ||
|} | |} | ||
Line 141: | Line 163: | ||
{| width='100%' | {| width='100%' | ||
| width='120' | '''Signatures''' | | width='120' | '''Signatures''' | ||
− | |{{Func|map:put|$ | + | |{{Func|map:put|$map as map(*), $key as xs:anyAtomicType, $value as item()*|map(*)}} |
|- | |- | ||
| '''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' | '''Signatures''' | | width='120' | '''Signatures''' | ||
− | |{{Func|map:remove|$ | + | |{{Func|map:remove|$map as map(*), $keys as xs:anyAtomicType*|map(*)}}<br/> |
|- | |- | ||
| '''Summary''' | | '''Summary''' | ||
− | | Constructs a new map by removing entries from an existing map. The entries in the new map correspond to the entries of {{Code|$ | + | | 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 keys; the input map is returned unchanged. | No failure occurs if the input map contains no entry with the supplied keys; the input map is returned unchanged. | ||
|- | |- | ||
| '''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' | '''Signatures''' | | width='120' | '''Signatures''' | ||
− | |{{Func|map:size|$ | + | |{{Func|map:size|$map as map(*)|xs:integer}}<br/> |
|- | |- | ||
| '''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. |
|- | |- | ||
| '''Examples''' | | '''Examples''' | ||
Line 176: | Line 200: | ||
|} | |} | ||
+ | =Changelog= | ||
− | + | ;Version 8.6 | |
− | + | * Added: [[#map:find|map:find]] | |
+ | * Updated: [[#map:merge|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 | ;Version 8.4 | ||
Line 184: | Line 210: | ||
;Version 8.0 | ;Version 8.0 | ||
− | + | * Added: [[#map:for-each|map:for-each]], [[#map:merge|map:merge]], [[#map:put|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 192: | Line 217: | ||
;Version 7.8 | ;Version 7.8 | ||
− | |||
* Updated: map syntax <code>map { 'key': 'value' }</code> | * Updated: map syntax <code>map { 'key': 'value' }</code> | ||
* Added: [[#map:serialize|map:serialize]] | * Added: [[#map:serialize|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> |
Revision as of 17:24, 16 January 2019
This XQuery Module contains functions for manipulating maps. Maps have been introduced with XQuery 3.1 and are described in detail in the XQuery Functions and Operators 3.1 specification.
Contents
Conventions
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
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
Signatures | 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
Signatures | 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
Signatures | 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
Signatures | map:for-each($map as map(*), $function as function(xs:anyAtomicType, item()*) as item()*) as item()*
|
Summary | Applies the specified $function 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
Signatures | 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
Signatures | 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
Signatures | map:merge($maps as map(*)*) as map(*) map:merge($maps as map(*)*, $options as 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
Signatures | 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
Signatures | 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
Signatures | 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
- 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' })