Changes

Jump to navigation Jump to search
m
Text replacement - "<syntaxhighlight lang="xquery">" to "<pre lang='xquery'>"
This [[Module Library|XQuery Module]] adds some useful higher-order functions, additional to the [[Higher-Order Functions]] provided by the official specification.
 
With {{Announce|Version 11}}, many functions have been removed in favor of new features of XQuery 4:
 
{|
|- valign="top"
| '''BaseX 10'''
| '''XQuery 4'''
|- valign="top"
| {{Code|hof:drop-while}}
| [https://qt4cg.org/specifications/xpath-functions-40/Overview.html#func-drop-while <code>fn:items-starting-where</code>]
|- valign="top"
| {{Code|hof:id}}
| [https://qt4cg.org/specifications/xpath-functions-40/Overview.html#func-identity <code>fn:identity</code>]
|- valign="top"
| {{Code|hof:until}}
| [https://qt4cg.org/specifications/xpath-functions-40/Overview.html#func-iterate-while <code>fn:iterate-while</code>]
|- valign="top"
| {{Code|hof:take-while}}
| [https://qt4cg.org/specifications/xpath-functions-40/Overview.html#func-take-while <code>fn:items-before</code>]
|}
=Conventions=
All functions in this module are assigned to the {{Code|<code><nowiki>http://basex.org/modules/hof}} </nowiki></code> namespace, which is statically bound to the {{Code|hof}} prefix.<br/>
=FunctionsLoops=
==hof:id=={||-| width='90' | '''Signatures'''|{{Func|hof:id|$expr as item()*|item()*}}|-| '''Summary'''|Returns its argument unchanged. This function isn't useful on its own, but can be used as argument to other higher-order functions.|-| '''Examples'''|* {{Code|hof:id(1 to 5)}} returns {{Code|1 2 3 4 5}}* With higherfold-order functions:<pre classleft1="brush:xquery">let $sort-by := function($f, $seq) { for $x in $seq order by $f($x) return $x }let $sort := $sort-by(hof:id#1, ?), $reverse-sort := $sort-by(function($x) { -$x }, ?)return ( $sort((1, 5, 3, 2, 4)), '|', $reverse-sort((1, 5, 3, 2, 4)))</pre>returns: <code>1 2 3 4 5 | 5 4 3 2 1</code>|}
==hof:const=={|width='100%'|-valign="top"| width='90120' | '''SignaturesSignature'''|{{Func|<pre>hof:const|fold-left1( $input as item()+, $expr action as function(item()*, $ignored item()) as item()*|) as item()*}}</pre>|-valign="top"
| '''Summary'''
|Returns its first argument unchanged and irgores Works the second. This function isn't useful on its own, but can be used same as argument to other higher[[Higher-Order Functions#fn:fold-left|fn:fold-order functionsleft]], e.g. when but does not need a function combining two values is expected and one only wants to retain seed, because the left onesequence must be non-empty.|-valign="top"
| '''Examples'''
|
* {{Code|hof:const(42, 1337)}} returns {{Code|42}}.* With higherfold-order functions:<pre class="brush:xquery">let $zip-sum := functionleft1($f, $seq11 to 10, $seq2) { sum(map-pairs($f, $seq1, $seq2)) }let $sum-all := $zip-sum(function($a, $b) { $a + $b }, ?, ?), $sum-left := $zip-sum(hof:const#2, ?, ?)return ( $sum-all((1, 1, 1, 1, 1), 1 to 5), $sum-left((1, 1, 1, 1, 1), 1 to 5))</pre>* Another use-case: When inserting a key into a map, }} returns {{Code|$f55}} descides how to combine the new value with a possibly existing old one. * {{Code|hof:const}} here means ignoring the old value, so that's normal insertion.<pre class="brush:xquery">let $insertfold-with := functionleft1($f, $map, $k, $v) { let $old := $map($k), $new := if($old) then $f($v, $old) else $v return map:new(($map, map{ $k := $new })) }let $map := map{ 'foo' := 1 }let $add := $insert-with(function($a, $b) {$a + $b}, ?, ?, ?)}} throws {{Code|XPTY0004}}, $insert := $insert-with(hof:const#2, ?, ?, ?)return ( $add($map, 'foo', 2)('foo'), $insert($map, 'foo', 42)('foo'))</pre>returns because {{Code|3 42$seq}}has to be non-empty.
|}
==hof:foldscan-left1=left={||-| width='90' | '''Signatures'''|{{Func|hof:fold-left1|$f as function(item()*, item()) as item()*, $seq as item()+)|item()*}}|-| '''Summary'''|Works the same as [[Higher-Order_Functions#fn:fold-left($f, $seed, $seq)|fn:fold-left($f, $seed, $seq)]], but doesn't need a seed, because the sequence must be non-empty.|-| '''Examples'''|* {{Code|hof:fold-left1(function($a, $b) { $a + $b }, 1 to 10)}} returns {{Code|55}}.* {{Code|hof:fold-left1(function($a, $b) { $a + $b }, ())}} throws {{Code|XPTY0004}}, because {{Code|$seq}} has to be non-empty.|}
==hof:until=={|width='100%'|-valign="top"| width='90120' | '''SignaturesSignature'''|{{Func|<pre>hof:until|scan-left( $pred input as functionitem()*, $zero as item()*) as xs:boolean, $f action as function(item()*) as , item()*, $start ) as item()*|) as item()*}}</pre>|-valign="top"
| '''Summary'''
|Applies This function is similar to [[Higher-Order Functions#fn:fold-left|fn:fold-left]], but it returns a list of successive reduced values from the left. It is equivalent to:<pre lang='xquery'>declare function hof:scan-left($input, $acc, $action) {{Code| if(empty($input)) then $acc else ( $acc, hof:scan-left(tail($f}} to the initial value {{Code|input), $start}} until the predicate {{Code|action($pred}} applied to the result returns {{Code|trueacc, head($input)), $action) )}}.;</pre>|-valign="top"
| '''Examples'''
|
* {{Code|hof:until(function($x) { $x ge 1000 }, function($y) { 2 * $y }, 1)}} returns {{Code|1024}}.* Calculating the square-root of a number by iteratively improving an initial guessReturns triangular numbers:<pre classlang="brush:'xquery"'>let $sqrt := function($x as xs:double) as xs:double { hof:untilscan-left( 1 to 10, 0, function($res) { abs($res * $res - $x) < 0.00001 }a, function($guessb) { ($guess a + $x div $guess) div 2 b }, $x )}return $sqrt(25)
</pre>
returns {{Code|5.000000000053722}}.
|}
 
=Sorting=
==hof:top-k-by==
{{Mark|Introduced with Version 7.2:}} {|width='100%'|-valign="top"| width='90120' | '''SignaturesSignature'''|{{Func|<pre>hof:top-k-by|( $seq input as item()*, $sort-key as function(item()) as item(), $k as xs:integer)|as item()*}}</pre>|-valign="top"
| '''Summary'''
|Returns the {{Code|$k}} items in {{Code|$seqinput}} that are greatest when sorted by the result of {{Code|$fkey}} applied to the item. The function is a much more efficient implementation of the following scheme:<pre classlang="brush:'xquery"'>( for $x item in $seqinput order by $sort-key($xitem) descending return $xitem
)[position() <= $k]
</pre>
|-valign="top"
| '''Examples'''
|
==hof:top-k-with==
{{Mark|Introduced with Version 7.2:}} {|width='100%'|-valign="top"| width='90120' | '''SignaturesSignature'''|{{Func|<pre>hof:top-k-with|( $seq input as item()*, $lt comparator as function(item(), item()) as xs:boolean, $k as xs:integer)|as item()*}}</pre>|-valign="top"
| '''Summary'''
|Returns the {{Code|$k}} items in {{Code|$seqinput}} that are greatest when sorted in the order of the ''less-than'' predicate {{Code|$ltcomparator}}. The function is a general version of {{CodeFunction||hof:top-k-by($seq, $sort-key, $k)}}.|-valign="top"
| '''Examples'''
|
* {{Code|hof:top-k-with(1 to 1000, function($a, $b) { $a lt $b }, 5)}} returns {{Code|1000 999 998 997 996}}
* {{Code|hof:top-k-with(-5 to 5, function($a, $b) { abs($a) gt abs($b) }, 5)}} returns {{Code|0 1 -1 2 -2}}
|}
 
=Identity=
 
==hof:const==
 
{| width='100%'
|- valign="top"
| width='120' | '''Signature'''
|<pre>hof:const(
$input as item()*,
$ignore as item()*
) as item()*</pre>
|- valign="top"
| '''Summary'''
|Returns its first argument unchanged and ignores the second. This function isn’t useful on its own, but can be used as argument to other higher-order functions, e.g., when a function combining two values is expected and one only wants to retain the left one.
|- valign="top"
| '''Examples'''
|
* {{Code|hof:const(42, 1337)}} returns {{Code|42}}.
* With higher-order functions:
<pre lang='xquery'>
let $zip-sum := function($f, $seq1, $seq2) {
sum(for-each-pair($seq1, $seq2, $f))
}
let $sum-all := $zip-sum(function($a, $b) { $a + $b }, ?, ?)
let $sum-left := $zip-sum(hof:const#2, ?, ?)
return (
$sum-all((1, 1, 1, 1, 1), 1 to 5),
$sum-left((1, 1, 1, 1, 1), 1 to 5)
)
</pre>
* Another use-case: When inserting a key into a map, {{Code|$f}} decides how to combine the new value with a possibly existing old one. {{Code|hof:const}} here means ignoring the old value, so that's normal insertion.
<pre lang='xquery'>
let $insert-with := function($f, $map, $k, $v) {
let $old := $map($k)
let $new := if($old) then $f($v, $old) else $v
return map:merge(($map, map:entry($k, $new)))
}
let $map := map { 'foo': 1 }
let $add := $insert-with(function($a, $b) { $a + $b }, ?, ?, ?)
let $ins := $insert-with(hof:const#2, ?, ?, ?)
return (
$add($map, 'foo', 2)('foo'),
$ins($map, 'foo', 42)('foo')
)
</pre>
returns {{Code|3 42}}
|}
=Changelog=
;Version 711.20* Removed: {{Code|hof:until}} (replaced with {{Code|fn:iterate-while}}, {{Code|hof:if}} (replaced with {{Code|fn:identity}}, {{Code|hof:drop-while}} (replaced with {{Code|fn:items-starting-where}}), {{Code|hof:take-while}} (replaced with {{Code|fn:items-before}}) ;Version 9.5* Added: {{Function||hof:drop-while}}
;Version 8.1* Added: [[#hof:top-k-by{{Function||hof:topscan-k-by]]left}}, [[#hof:top-k-with{{Function||hof:toptake-k-with]]* Removed: [[#hof:iterate|hof:iterate]]while}}
===;Version 7.0===2* Added: {{Function||hof:top-k-by}}, {{Function||hof:top-k-with}}* Removed: hof:iterate
;Version 7.0
* module added
 
[[Category:XQuery]]
Bureaucrats, editor, reviewer, Administrators
13,554

edits

Navigation menu