Changes

Jump to navigation Jump to search
2,736 bytes added ,  10:29, 21 August 2020
no edit summary
=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:idfold-left1== {|width='100%'
|-
| width='90120' | '''Signatures'''|{{Func|hof:idfold-left1|$expr seq as item()+, $f as function(item()*, item()) as item()*|item()*}}
|-
| '''Summary'''
|Returns its argument unchanged. This function isn't useful on its ownWorks the same as [[Higher-Order Functions#fn:fold-left|fn:fold-left]], but can does not need a seed, because the sequence must be used as argument to other highernon-order functionsempty.
|-
| '''Examples'''
|
* {{Code|hof:idfold-left1(1 to 510, function($a, $b) { $a + $b })}} returns {{Code|1 2 3 4 555}}.* With higher-order functions:<pre class="brush{{Code|hof:xquery">let $sortfold-by := left1((), function($fa, $seqb) { for $x in a + $seq order by $f($xb }) return $x }let $sort := $sort-by(hof:id#1, ?), $reverse-sort := $sort-by(function($x) } throws {{ -$x Code|XPTY0004}}, ?)return ( $sort((1, 5, 3, 2, 4)), 'because {{Code|', $reverseseq}} has to be non-sort((1, 5, 3, 2, 4)))</pre>returns: <code>1 2 3 4 5 | 5 4 3 2 1</code>empty.
|}
==hof:constuntil== {|width='100%'
|-
| width='90120' | '''Signatures'''|{{Func|hof:constuntil|$expr pred as function(item()*) as xs:boolean, $f as function(item()*) as item()*, $ignored start as item()*|item()*}}
|-
| '''Summary'''
|Returns its first argument unchanged and irgores Applies the secondpredicate function {{Code|$pred}} to {{Code|$start}}. This function isn't useful on its ownIf the result is {{Code|false}}, {{Code|$f}} is invoked with the start value – or, but can be used as argument to other higher-order functionssubsequently, e.g. when a with the result of this function combining two values is expected and one only wants to retain – until the left onepredicate function returns {{Code|true()}}.
|-
| '''Examples'''
|
* {{Code|hof:const(42, 1337)}} returns {{Code|42}}.* With higher-order functionsDoubles a numeric value until a maximum is reached:<pre classsyntaxhighlight lang="brush:xquery">let $zip-sum hof:= until( function($f, $seq1, $seq2output) { sum(map-pairs($foutput ge 1000 }, $seq1, $seq2)) }let $sum-all := $zip-sum(function($a, $binput ) { 2 * $a + $b input }, ?, ?), $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)
)
</presyntaxhighlight>* Another useCalculates the square-case: When inserting a key into root of a map, {{Code|$f}} descides how to combine the new value with a possibly existing old one. {{Code|hofnumber by iteratively improving an initial guess:const}} here means ignoring the old value, so that's normal insertion.<pre classsyntaxhighlight lang="brush:xquery">let $insert-with sqrt := function($f, $map, $k, $vinput as xs:double) as xs:double { let $old hof:= $mapuntil($k), $new := if function($oldresult) then { abs($f(result * $v, result - $oldinput) else $v< 0.00001 }, return map:newfunction($guess) { ($map, map{ guess + $k := input div $new guess) div 2 })), $input })let $map := map{ 'foo' := 1 }let return $add := $insert-with(functionsqrt($a, $b25) </syntaxhighlight>* Returns {{$a + $bCode|OK}}, ?, ?, ?),as the predicate is evaluated first: $insert :<syntaxhighlight lang= $insert-with("xquery">hof:const#2, ?, ?, ?)return until( $addfunction($map, 'foo', 2_){ true('foo')}, $insertfunction($map, 'foo', 42_){ error() }, 'fooOK')
)
</presyntaxhighlight>returns {{Code|3 42}}
|}
==hof:foldscan-left1left== {|width='100%'
|-
| width='90120' | '''Signatures'''|{{Func|hof:foldscan-left1left|$f seq as function(item()*, $start as item()) *, $f as function(item()*, $seq item()) as item()+)*|item()*}}
|-
| '''Summary'''
|Works the same as This function is similar to [[Higher-Order_FunctionsOrder Functions#fn:fold-left|fn:fold-left]], but it returns a list of successive reduced values from the left. It is equivalent to:<syntaxhighlight lang="xquery">declare function hof:scan-left($fseq, $seedacc, $f) { if(empty($seq)|fn) then $acc else ( $acc, hof:foldscan-left(tail($seq), $f, ($seedacc, head($seq)]]), but doesn't need a seed, because the sequence must be non-empty.$f) )};</syntaxhighlight>
|-
| '''Examples'''
|
* {{Code|Returns triangular numbers:<syntaxhighlight lang="xquery">hof:foldscan-left1(functionleft($a, $b) { $a + $b }, 1 to 10)}} returns {{Code|55}}.* {{Code|hof:fold-left1(, 0, function($a, $b) { $a + $b }, ())}} throws {{Code|XPTY0004}}, because {{Code|$seq}} has to be non-empty.</syntaxhighlight>
|}
==hof:untiltake-while== {|width='100%'
|-
| width='90120' | '''Signatures'''|{{Func|hof:untiltake-while|$pred seq as function(item()*) as xs:boolean, $f pred as function(item()*) as item()*, $start as item()*xs:boolean|item()*}}
|-
| '''Summary'''
|Applies the The function {{Code|$f}} to the initial value {{Code|returns items of <code>$start}} until seq</code> as long as the predicate {{Code|<code>$pred}} applied </code> is satisfied. It is equivalent to the result returns :<syntaxhighlight lang="xquery">declare function hof:take-while($seq, $pred) {{Code|true if(empty($seq) or not($pred(head($seq)))) then () else ( head($seq), hof:take-while(tail($seq), $pred) )}}.;</syntaxhighlight>
|-
| '''Examples'''
|
* {{Code|Computes at most 100 random integers, but stops if an integer is smaller than 10:<syntaxhighlight lang="xquery">hof:untiltake-while( (1 to 100) ! random:integer(50), function($x) { $x ge 1000 >= 10 }, function($y) </syntaxhighlight>|} ==hof:drop-while== { 2 * $y {Mark|Introduced with Version 9.5.}, 1)}} returns  {| width='100%'|-| width='120' | '''Signatures'''|{{CodeFunc|hof:drop-while|$seq as item()*, $pred as function(item()) as xs:boolean|1024item()*}}.* Calculating the square|-root | '''Summary'''|The function skips all items of a number by iteratively improving an initial guess<code>$seq</code> until the predicate <code>$pred</code> is not satisfied anymore. It is equivalent to:<pre classsyntaxhighlight lang="brush:xquery">let $sqrt declare function hof:= functiondrop-while($x as xs:doubleseq, $pred) as xs:double { hof:untilif($pred( functionhead($resseq))) { absthen ($res * $res hof:drop- while(tail($xseq) < 0.00001 },$pred) function($guess ) { else ($guess + $x div $guess) div 2 }, $xseq
)
}return $sqrt(25);</presyntaxhighlight>returns {{Code|5-| '''Examples'''|Returns the name of the first file that does not exist on disk:<syntaxhighlight lang="xquery">hof:drop-while( (1 to 1000) ! (.000000000053722}}|| '.log'), file:exists#1)[1]</syntaxhighlight>
|}
 
=Sorting=
==hof:top-k-by==
{{Mark|Introduced with Version 7.2:}} {|width='100%'
|-
| width='90120' | '''Signatures'''|{{Func|hof:top-k-by|$seq as item()*, $sort-key as function(item()) as item(), $k as xs:integer)|item()*}}
|-
| '''Summary'''
|Returns the {{Code|$k}} items in {{Code|$seq}} that are greatest when sorted by the result of {{Code|$f}} applied to the item. The function is a much more efficient implementation of the following scheme:
<pre classsyntaxhighlight lang="brush:xquery">( for $x in $seq order by $sort-key($x) descending return $x
)[position() <= $k]
</presyntaxhighlight>
|-
| '''Examples'''
* {{Code|hof:top-k-by(1 to 1000, hof:id#1, 5)}} returns {{Code|1000 999 998 997 996}}
* {{Code|hof:top-k-by(1 to 1000, function($x) { -$x }, 3)}} returns {{Code|1 2 3}}
* {{Code|<code>hof:top-k-by(<x a='1' b='2' c='3'/>/@*, xs:integer#1, 2)/node-name()}} </code> returns {{Code|c b}}
|}
==hof:top-k-with==
{{Mark|Introduced with Version 7.2:}} {|width='100%'
|-
| width='90120' | '''Signatures'''|{{Func|hof:top-k-with|$seq as item()*, $lt as function(item(), item()) as xs:boolean, $k as xs:integer)|item()*}}
|-
| '''Summary'''
* {{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}}
|}
 
=IDs=
 
==hof:id==
 
{| width='100%'
|-
| width='120' | '''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 higher-order functions:
<syntaxhighlight lang="xquery">
let $sort := sort(?, (), hof:id#1)
let $reverse-sort := sort(?, (), function($x) { -$x })
return (
$sort((1, 5, 3, 2, 4)),
'|',
$reverse-sort((1, 5, 3, 2, 4))
)
</syntaxhighlight>
returns: <code>1 2 3 4 5 | 5 4 3 2 1</code>
|}
 
==hof:const==
 
{| width='100%'
|-
| width='120' | '''Signatures'''
|{{Func|hof:const|$expr as item()*, $ignored as item()*|item()*}}
|-
| '''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.
|-
| '''Examples'''
|
* {{Code|hof:const(42, 1337)}} returns {{Code|42}}.
* With higher-order functions:
<syntaxhighlight 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)
)
</syntaxhighlight>
* 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.
<syntaxhighlight 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')
)
</syntaxhighlight>
returns {{Code|3 42}}
|}
=Changelog=
===;Version 79.2===5* Added: [[#hof:drop-while|hof:drop-while]] ;Version 8.1* Added: [[#hof:scan-left|hof:scan-left]], [[#hof:take-while|hof:take-while]]
;Version 7.2
* Added: [[#hof:top-k-by|hof:top-k-by]], [[#hof:top-k-with|hof:top-k-with]]
* Removed: [[#hof:iterate|hof:iterate]] ===Version 7.0===
;Version 7.0
* module added
 
[[Category:XQuery]]
Bureaucrats, editor, reviewer, Administrators
13,550

edits

Navigation menu