(:~ : Additional functions for XQuery 3.0 maps. : : @author Leo Wörteler : @version 0.0.2 :) module namespace map-extras='http://www.basex.org/modules/map-extras'; (:~ : Insert with a combining function. insert-with($f, $key, $value, $map) : will insert map:entry($key, $value) into $map if : $key does not exist in the map. If the key does exist, the function : will insert $f($new-value, $old-value). : : @param $f combining function : @param $key key to insert : @param $value value to insert : @param $map map to insert into : @return new map where the entry is inserted :) declare function map-extras:insert-with( $f as function(item()*, item()*) as item()*, $key as item(), $value as item()*, $map as map(*) ) as map(*) { map:merge(($map, map:entry($key, if(map:contains($map, $key)) then $f($value, $map($key)) else $value ))) }; (:~ : Inserts a key-value pair into a map. If an entry with the key $key : already exists in the map, it is replaced by the new one. : : @param $key key to insert : @param $value value to insert : @param $map map to insert into : @return map where the key-value pair was inserted :) declare %public function map-extras:insert( $key as item(), $value as item()*, $map as map(*) ) as map(*) { map:merge(($map, map:entry($key, $value))) }; (:~ : Fold the keys and values in the map using the given with the given : combining function $f($). : Let (($k1,$v1), ..., ($kn, $vn)) be the key-value pairs in the : given map $map, then the result is calculated by: : $f(... $f($f($start, $k1, $v1), $k2, $v2), ...), $kn, $vn) : : @param $f left-associative combining function : @param $start start value : @param $map map to be folded : @return resulting value :) declare %public function map-extras:fold( $f as function(item()*, item(), item()*) as item()*, $start as item()*, $map as map(*) ) as item()* { fold-left( function($val, $key) { $f($val, $key, $map($key)) }, $start, map:keys($map) ) }; (:~ : Extracts all values from the map $map, returning : them in a sequence in arbitrary order. : : @param $map map to extract the values from : @return sequence of values :) declare %public function map-extras:values( $map as map(*) ) as item()* { $map?* }; (:~ : Applies the function $f to all values in the map. : The keys are not touched. : : @param $f function to be applies to all values : @param $map input map : @return copy of $map where all values $value : are replaced by $f($value) :) declare %public function map-extras:map( $f as function(item()*) as item()*, $map as map(*) ) as map(*) { map:merge( for $key in map:keys($map) return map:entry($key, $f($map($key))) ) }; (:~ : Maps a function over all entries of the map $map. : Each entry ($key, $value) in the map is replaced by a new : entry ($key, $f($key, $value)), the keys are not touched. : : @param $f function to be applies to all entries : @param $map input map : @return copy of $map where all values $value : are replaced by $f($key, $value) :) declare %public function map-extras:map-with-key( $f as function(item(), item()*) as item()*, $map as map(*) ) as map(*) { map:merge( for $key in map:keys($map) return map:entry($key, $f($key, $map($key))) ) };