The intersection of two maps is the set of key/value pairs that are the same in both of the maps. To find the intersection of two maps you can use the map intersection operator (*
), like this: $mapA * $mapB
. But what if you have an arbitrarily-long sequence of maps?
This is where folding becomes very handy. The fn:fold-left
function applies an operation to a sequence of values.
declare function local:intersect($maps as map:map*) as map:map* { fn:fold-left( function($left, $right) { $left * $right }, fn:head($maps), fn:tail($maps) ) }; let $mapA := map:new(( map:entry("a", "aardvark"), map:entry("b", "badger") )) let $mapB := map:new(( map:entry("a", "aardvark"), map:entry("b", "badger"), map:entry("d", "duck") )) let $mapC := map:new(( map:entry("a", "aardvark"), map:entry("b", "badger"), map:entry("c", "candidate") )) return ( local:intersect(($mapA, $mapB, $mapC)) )
The result is:
<map:map xmlns:map="https://marklogic.com/xdmp/map" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:xs="https://www.w3.org/2001/XMLSchema"> <map:entry key="b"> <map:value xsi:type="xs:string">badger</map:value> </map:entry> <map:entry key="a"> <map:value xsi:type="xs:string">aardvark</map:value> </map:entry> </map:map>
The fn:fold-left()
function applies a function to a series of values, with the result of one operation being input to the next.
fn:fold-left( function($left, $right) { $left + $right }, 1, (2, 3) )
The code above applies the specified function to the 1 and the first item in the sequence (2). These are added together, producing 3. That accumulated value and the next value in the sequence are then passed to the function. The new accumulated value becomes 3 + 3 = 6. The sequence is empty now, so fn:fold-left
is finished.
With the maps, the local:intersect()
function will use the intersect operator (*
) to combine $mapA
and $mapB
, then compare that result with $mapC
.
By continuing to use this website you are giving consent to cookies being used in accordance with the MarkLogic Privacy Statement.