On Fri, 2021-06-04 at 12:35 -0400, Graydon Saunders wrote:
declare function local:subtractSentences($before as xs:string*,$after as xs:string*) as xs:string* {
let $thisBefore as xs:string? := head($before) let $thisAfter as xs:string? := head($after)
return if (not(exists($thisBefore)) or not(exists($thisAfter))) then $after (: we're done because we're out of strings, but if we have any after left we want it :) else if (ends-with($thisAfter,$thisBefore)) then (replace($thisAfter,$thisBefore,''),local:subtractSentences(tail($bef ore),tail($after))) else ($thisAfter,local:subtractSentences($before,tail($after))) };
I'd be tempted to do this by constructing a regular expression on the fly, mapping whitespace in the input to \s+ in the expression and quoting \ elsewhere, and use a single replace().
Your problem is likely (ididn't check the BaseX query plan) that your final sequence constructor precludes tail optimization.
($thisAfter,local:subtractSentences($before,tail($after))
either use one of the fold-left or fold-right functions, or pass $thisAfter as an argument to your function and return it at the end, perhaps.
Liam