Difference between revisions of "Map Module"

From BaseX Documentation
Jump to navigation Jump to search
Line 21: Line 21:
  
 
==map:contains==
 
==map:contains==
 +
 
{| width='100%'
 
{| width='100%'
 
| width='120' | '''Signatures'''
 
| width='120' | '''Signatures'''
|{{Func|map:contains|$input as map(*), $key as xs:anyAtomicType|xs:boolean}}
+
|{{Func|map:contains|$map as map(*), $key as xs:anyAtomicType|xs:boolean}}
 
|-
 
|-
 
| '''Summary'''
 
| '''Summary'''
| Returns true if the ''map'' supplied as {{Code|$input}} 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}}.
+
| 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 38: Line 39:
  
 
==map:entry==
 
==map:entry==
 +
 
{| width='100%'
 
{| width='100%'
 
| width='120' | '''Signatures'''
 
| width='120' | '''Signatures'''
Line 69: Line 71:
 
{| width='100%'
 
{| width='100%'
 
| width='120' | '''Signatures'''
 
| width='120' | '''Signatures'''
|{{Func|map:for-each|$input as map(*), $fun as function(xs:anyAtomicType, item()*) as item()*|item()*}}
+
|{{Func|map:for-each|$map as map(*), $fun as function(xs:anyAtomicType, item()*) as item()*|item()*}}
 
|-
 
|-
 
| '''Summary'''
 
| '''Summary'''
|Applies a function to every entry of the map {{Code|$input}} and returns the results as a sequence. The function supplied as {{Code|$fun}} takes two arguments. It is called supplying the key of the map entry as the first argument, and the associated value as the second argument.
+
|Applies a function to every entry of the supplied {{Code|$map}} and returns the results as a sequence. The function supplied as {{Code|$fun}} takes two arguments. It is called supplying the key of the map entry as the first argument, and the associated value as the second argument.
 
|-
 
|-
 
| '''Examples'''
 
| '''Examples'''
Line 85: Line 87:
  
 
==map:get==
 
==map:get==
 +
 
{| width='100%'
 
{| width='100%'
 
| width='120' | '''Signatures'''
 
| width='120' | '''Signatures'''
|{{Func|map:get|$input as map(*), $key as xs:anyAtomicType|item()*}}
+
|{{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 ''map'' supplied as {{Code|$input}} 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}}.
+
|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|$input}} is a map, the expression {{Code|$input($K)}} is equivalent to {{Code|get($input, $K)}}. Similarly, the expression {{Code|get(get(get($input, 'employee'), 'name'), 'first')}} can be written as {{Code|$input('employee')('name')('first')}}.
+
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'''
Line 102: Line 105:
  
 
==map:keys==
 
==map:keys==
 +
 
{| width='100%'
 
{| width='100%'
 
| width='120' | '''Signatures'''
 
| width='120' | '''Signatures'''
|{{Func|map:keys|$input as map(*)|xs:anyAtomicType*}}
+
|{{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 any ''map'' as its {{Code|$input}} argument 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.
+
|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 115: Line 119:
  
 
==map:merge==
 
==map:merge==
 +
 +
{{Mark|Updated with Version 8.6:}} Signature extended with options argument. By default, value of first key is now adopted.
  
 
{| width='100%'
 
{| width='100%'
 
| width='120' | '''Signatures'''
 
| width='120' | '''Signatures'''
|{{Func|map:merge|$input as map(*)*|map(*)}}
+
|{{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 maps supplied in the {{Code|$input}} argument. The maps are combined as follows:
+
| 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 value present in the union of the input maps, where keys are considered distinct according to the rules of the {{Code|distinct-values}} function.
+
# The {{Code|$options} argument defines how duplicate keys are handled. Currently, the single option {{Code|duplicates}} exists, and the allowed values are {{Code|use-first}}, {{Code|use-last}}, {{Code|use-combine}} and {{Code|reject}}.
# The associated value for each such key is taken from the last map in the input sequence {{Code|$input}} that contains an entry with this key.
 
 
 
There is no requirement that the supplied input maps should have the same or compatible types. The type of a map (for example {{Code|map(xs:integer, xs:string)}}) is descriptive of the entries it currently contains, but is not a constraint on how the map may be combined with other maps.
 
 
|-
 
|-
 
| '''Examples'''
 
| '''Examples'''
Line 133: Line 136:
 
* {{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>.
 
* <code>map:merge(($week, map { 7: "Unbekannt" }))</code> creates <code>map { 0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch", 4: "Donnerstag", 5: "Freitag", 6: "Samstag", 7: "Unbekannt" }</code>.
 
* <code>map:merge(($week, map { 7: "Unbekannt" }))</code> creates <code>map { 0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch", 4: "Donnerstag", 5: "Freitag", 6: "Samstag", 7: "Unbekannt" }</code>.
* <code>map:merge(($week, map { 6: "Sonnabend" }))</code> creates <code>map { 0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch", 4: "Donnerstag", 5: "Freitag", 6: "Sonnabend" }</code>.
+
* <code>map:merge((map { 1:'a' }, map { 1:'b' }), map { 'duplicates':'combine' })</code> creates <code>map { 1: ("a", "b") }</code>.
 
|}
 
|}
  
Line 140: Line 143:
 
{| width='100%'
 
{| width='100%'
 
| width='120' | '''Signatures'''
 
| width='120' | '''Signatures'''
|{{Func|map:put|$input as map(*), $key as xs:anyAtomicType, $value as item()*|map(*)}}
+
|{{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|$input}} argument and a new entry composed by {{Code|$key}} and {{Code|$value}}. The semantics of this function are equivalent to <code>map:merge(($input, map { $key, $value }))</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, map { $key, $value }))</code>
 
|}
 
|}
  
 
==map:remove==
 
==map:remove==
 +
 
{| width='100%'
 
{| width='100%'
 
| width='120' | '''Signatures'''
 
| width='120' | '''Signatures'''
|{{Func|map:remove|$input as map(*), $keys as xs:anyAtomicType*|map(*)}}<br/>
+
|{{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|$input}}, excluding entries supplied via {{Code|$keys}}.
+
| 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.
 
|-
 
|-
Line 162: Line 166:
  
 
==map:size==
 
==map:size==
 +
 
{| width='100%'
 
{| width='100%'
 
| width='120' | '''Signatures'''
 
| width='120' | '''Signatures'''
|{{Func|map:size|$input as map(*)|xs:integer}}<br/>
+
|{{Func|map:size|$map as map(*)|xs:integer}}<br/>
 
|-
 
|-
 
| '''Summary'''
 
| '''Summary'''
| Returns a the number of entries in the supplied map. The function takes any ''map'' as its {{Code|$input}} argument and returns the number of entries that are present in the map.
+
| 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 175: Line 180:
 
|}
 
|}
  
 +
=Changelog=
  
 
+
;Version 8.6
=Changelog=
+
* Updated: [[#map:merge|map:merge]] signature extended with options argument. By default, value of first key is now adopted.
  
 
;Version 8.4
 
;Version 8.4
Line 183: Line 189:
  
 
;Version 8.0
 
;Version 8.0
 
 
* Added: <code>[[#map:for-each|map:for-each]]</code>, <code>[[#map:merge|map:merge]]</code>, <code>[[#map:put|map:put]]</code>
 
* Added: <code>[[#map:for-each|map:for-each]]</code>, <code>[[#map:merge|map:merge]]</code>, <code>[[#map:put|map:put]]</code>
 
* Removed: support for collations (in accordance with the XQuery 3.1 spec).
 
* Removed: support for collations (in accordance with the XQuery 3.1 spec).
Line 191: Line 196:
  
 
;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 14:08, 11 October 2016

This XQuery Module contains functions for manipulating maps, which has been introduced with XQuery 3.1.

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 as map(*) := map {
  0: "Sonntag",
  1: "Montag",
  2: "Dienstag",
  3: "Mittwoch",
  4: "Donnerstag",
  5: "Freitag",
  6: "Samstag"
};

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 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

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: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("Su", "Sunday"),
  map:entry("Mo", "Monday"),
  map:entry("Tu", "Tuesday"),
  map:entry("We", "Wednesday"),
  map:entry("Th", "Thursday"),
  map:entry("Fr", "Friday"),
  map:entry("Sa", "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:for-each

Signatures map:for-each($map as map(*), $fun as function(xs:anyAtomicType, item()*) as item()*) as item()*
Summary Applies a function to every entry of the supplied $map and returns the results as a sequence. The function supplied as $fun takes two arguments. It is called supplying the key of the map entry as the first argument, and the associated value as the second argument.
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($a, $b) { $a + $b }
)

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 () 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 "Donnerstag".
  • 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

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:keys(map { 1: "yes", 2: "no" }) returns (1,2).

map:merge

Template:Mark Signature extended with options argument. By default, value of first key is now adopted.

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:
  1. There is one entry in the new map for each distinct key present in the union of the input maps.
  2. The {{Code|$options} argument defines how duplicate keys are handled. Currently, the single option duplicates exists, and the allowed values are use-first, use-last, use-combine and reject.
Examples
  • map:merge(()) creates an empty map.
  • map:merge((map:entry(0, "no"), map:entry(1, "yes"))) creates map { 0: "no", 1: "yes" }.
  • map:merge(($week, map { 7: "Unbekannt" })) creates map { 0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch", 4: "Donnerstag", 5: "Freitag", 6: "Samstag", 7: "Unbekannt" }.
  • map:merge((map { 1:'a' }, map { 1:'b' }), map { 'duplicates':'combine' }) creates map { 1: ("a", "b") }.

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, map { $key, $value }))

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:remove($week, 4) creates map { 0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch", 5: "Freitag", 6: "Samstag" }.
  • map:remove($week, 23) creates map { 0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch", 4: "Donnerstag", 5: "Freitag", 6: "Samstag" }.

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
  • map:size(map:merge(())) returns 0.
  • map:size(map { "true": 1, "false": 0 }) returns 2.

Changelog

Version 8.6
  • Updated: map:merge signature extended with options argument. By default, value of first key is now adopted.
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' })