Examples of Collating sequences.
Author: Chris Wallace
| Task | where one sequence is the primary seqence, one could iterate through that sequence and look up in the secondary. |
|---|---|
| XQuery |
declare function local:merge($primary, $secondary as item()* ) as item()* {
for $item in $primary
return
if (exists($secondary[.=$item]))
then <matched>{$item}</matched>
else <missing>{$item}</missing>
};
let $a :=
<list>
<item>a</item>
<item>b</item>
<item>c</item>
<item>d</item>
<item>g</item>
<item>j</item>
</list>
let $b :=
<list>
<item>b</item>
<item>e</item>
<item>h</item>
<item>j</item>
<item>k</item>
</list>
return local:merge($a/item,$b/item)
|
| Output |
<missing>
<item>a</item>
</missing>
<matched>
<item>b</item>
</matched>
<missing>
<item>c</item>
</missing>
<missing>
<item>d</item>
</missing>
<missing>
<item>g</item>
</missing>
<matched>
<item>j</item>
</matched>
|
| Elapsed Time (ms) | 13 |
| Task | We could test using a qualified expression. |
|---|---|
| XQuery |
declare function local:merge($primary, $secondary as item()* ) as item()* {
for $item1 in $primary
return
if (some $item2 in $secondary satisfies $item2 = $item1)
then <matched>{$item1}</matched>
else <missing>{$item1}</missing>
};
let $a :=
<list>
<item>a</item>
<item>b</item>
<item>c</item>
<item>d</item>
<item>g</item>
<item>j</item>
</list>
let $b :=
<list>
<item>b</item>
<item>e</item>
<item>h</item>
<item>j</item>
<item>k</item>
</list>
return local:merge($a/item,$b/item)
|
| Output |
<missing>
<item>a</item>
</missing>
<matched>
<item>b</item>
</matched>
<missing>
<item>c</item>
</missing>
<missing>
<item>d</item>
</missing>
<missing>
<item>g</item>
</missing>
<matched>
<item>j</item>
</matched>
|
| Elapsed Time (ms) | 13 |
| Task | The merged sequences can be reversed to provide a symetric comparison |
|---|---|
| XQuery |
declare function local:merge($primary, $secondary as item()* ) as item()* {
for $item1 in $primary
return
if (some $item2 in $secondary satisfies $item2 = $item1)
then <matched>{$item1}</matched>
else <missing>{$item1}</missing>
};
let $a :=
<list>
<item>a</item>
<item>b</item>
<item>c</item>
<item>d</item>
<item>g</item>
<item>j</item>
</list>
let $b :=
<list>
<item>b</item>
<item>e</item>
<item>h</item>
<item>j</item>
<item>k</item>
</list>
return
<result>
<ab>
{local:merge($a/item,$b/item)}
</ab>
<ba>
{local:merge($b/item,$a/item) }
</ba>
</result>
|
| Output |
<result>
<ab>
<missing>
<item>a</item>
</missing>
<matched>
<item>b</item>
</matched>
<missing>
<item>c</item>
</missing>
<missing>
<item>d</item>
</missing>
<missing>
<item>g</item>
</missing>
<matched>
<item>j</item>
</matched>
</ab>
<ba>
<matched>
<item>b</item>
</matched>
<missing>
<item>e</item>
</missing>
<missing>
<item>h</item>
</missing>
<matched>
<item>j</item>
</matched>
<missing>
<item>k</item>
</missing>
</ba>
</result>
|
| Elapsed Time (ms) | 16 |
| Task | The elements are assumed to be in ascending order. |
|---|---|
| XQuery |
declare function local:merge($a, $b as item()* ) as item()* {
if (empty($a) and empty($b))
then ()
else if (empty ($b) or $a[1] lt $b[1])
then (<a>{$a[1]}</a>, local:merge(subsequence($a, 2), $b))
else if (empty($a) or $a[1] gt $b[1])
then (<b>{$b[1]}</b>, local:merge($a, subsequence($b,2)))
else (<match>{$a[1]}</match>,local:merge(subsequence($a,2), subsequence($b,2)))
};
let $a :=
<list>
<item>a</item>
<item>b</item>
<item>c</item>
<item>d</item>
<item>g</item>
<item>j</item>
</list>
let $b :=
<list>
<item>b</item>
<item>e</item>
<item>h</item>
<item>j</item>
<item>k</item>
</list>
return local:merge($a/item,$b/item)
|
| Output |
<a>
<item>a</item>
</a>
<match>
<item>b</item>
</match>
<a>
<item>c</item>
</a>
<a>
<item>d</item>
</a>
<b>
<item>e</item>
</b>
<a>
<item>g</item>
</a>
<b>
<item>h</item>
</b>
<match>
<item>j</item>
</match>
<b>
<item>k</item>
</b>
|
| Elapsed Time (ms) | 24 |
| Task | If the elements represent files in a file system and have dataTime attributes , we can use this algorithm to generate a list of update actions. Here the items are merely wrapped in a div to carry the update tags. Sample data taken from the Wikibook article |
|---|---|
| XQuery |
declare function local:time-merge($a, $b as item()* ) as item()* {
if (empty($a) and empty($b))
then ()
else if (empty ($b) or $a[1] lt $b[1])
then (<div class="add">{$a[1]}</div>, local:time-merge(subsequence($a, 2), $b))
else if (empty($a) or $a[1] gt $b[1])
then (<div class="delete">{$b[1]}</div>,local:time-merge($a, subsequence($b,2)))
else (<div class="{ if (xs:dateTime($a[1]/@dateTime) gt xs:dateTime($b[1]/@dateTime))
then "newer"
else "older"}">
{$a[1]}
</div>,
local:time-merge(subsequence($a,2), subsequence($b,2))
)
};
let $list1 :=
<list>
<item dateTime="2009-06-01T11:59:00.000-05:00">apples</item>
<item dateTime="2009-02-01T11:59:00.000-05:00">bananas</item>
<item dateTime="2009-02-01T11:59:00.000-05:00">cabbage</item>
<item dateTime="2009-02-01T11:59:00.000-05:00">carrots</item>
<item dateTime="2009-02-01T11:59:00.000-05:00">eggplant</item>
<item dateTime="2009-02-01T11:59:00.000-05:00">grapes</item>
</list>
let $list2 :=
<list>
<item dateTime="2009-01-01T11:59:00.000-05:00">apples</item>
<item dateTime="2009-02-01T11:59:00.000-05:00">bananas</item>
<item dateTime="2009-03-01T11:59:00.000-05:00">carrots</item>
<item dateTime="2009-02-01T11:58:00.000-05:00">eggplant</item>
<item dateTime="2009-02-01T12:00:00.000-05:00">grapes</item>
<item dateTime="2009-04-01T11:59:00.000-05:00">oranges</item>
</list>
return local:time-merge($list1/item, $list2/item)
|
| Output |
<div class="newer">
<item dateTime="2009-06-01T11:59:00.000-05:00">apples</item>
</div>
<div class="older">
<item dateTime="2009-02-01T11:59:00.000-05:00">bananas</item>
</div>
<div class="add">
<item dateTime="2009-02-01T11:59:00.000-05:00">cabbage</item>
</div>
<div class="older">
<item dateTime="2009-02-01T11:59:00.000-05:00">carrots</item>
</div>
<div class="newer">
<item dateTime="2009-02-01T11:59:00.000-05:00">eggplant</item>
</div>
<div class="older">
<item dateTime="2009-02-01T11:59:00.000-05:00">grapes</item>
</div>
<div class="delete">
<item dateTime="2009-04-01T11:59:00.000-05:00">oranges</item>
</div>
|
| Elapsed Time (ms) | 30 |
| Task | If the sequences to be merged are not in sorted order, then they can be sorted before merging using the same sort criteria as wil be used in the merge. |
|---|---|
| XQuery |
declare function local:time-merge($a, $b as item()* ) as item()* {
if (empty($a) and empty($b))
then ()
else if (empty ($b) or $a[1] lt $b[1])
then (<div class="add">{$a[1]}</div>, local:time-merge(subsequence($a, 2), $b))
else if (empty($a) or $a[1] gt $b[1])
then (<div class="delete">{$b[1]}</div>,local:time-merge($a, subsequence($b,2)))
else (<div class="{ if (xs:dateTime($a[1]/@dateTime) gt xs:dateTime($b[1]/@dateTime))
then "newer"
else "older"}">
{$a[1]}
</div>,
local:time-merge(subsequence($a,2), subsequence($b,2))
)
};
let $list1 :=
<list>
<item dateTime="2009-02-01T11:59:00.000-05:00">cabbage</item>
<item dateTime="2009-02-01T11:59:00.000-05:00">bananas</item>
<item dateTime="2009-02-01T11:59:00.000-05:00">carrots</item>
<item dateTime="2009-02-01T11:59:00.000-05:00">grapes</item>
<item dateTime="2009-02-01T11:59:00.000-05:00">eggplant</item>
<item dateTime="2009-06-01T11:59:00.000-05:00">apples</item>
</list>
let $list2 :=
<list>
<item dateTime="2009-03-01T11:59:00.000-05:00">carrots</item>
<item dateTime="2009-02-01T11:58:00.000-05:00">eggplant</item>
<item dateTime="2009-02-01T12:00:00.000-05:00">grapes</item>
<item dateTime="2009-04-01T11:59:00.000-05:00">oranges</item>
<item dateTime="2009-01-01T11:59:00.000-05:00">apples</item>
<item dateTime="2009-02-01T11:59:00.000-05:00">bananas</item>
</list>
return local:time-merge(
for $item in $list1/item order by $item return $item,
for $item in $list2/item order by $item return $item
)
|
| Output |
<div class="newer">
<item dateTime="2009-06-01T11:59:00.000-05:00">apples</item>
</div>
<div class="older">
<item dateTime="2009-02-01T11:59:00.000-05:00">bananas</item>
</div>
<div class="add">
<item dateTime="2009-02-01T11:59:00.000-05:00">cabbage</item>
</div>
<div class="older">
<item dateTime="2009-02-01T11:59:00.000-05:00">carrots</item>
</div>
<div class="newer">
<item dateTime="2009-02-01T11:59:00.000-05:00">eggplant</item>
</div>
<div class="older">
<item dateTime="2009-02-01T11:59:00.000-05:00">grapes</item>
</div>
<div class="delete">
<item dateTime="2009-04-01T11:59:00.000-05:00">oranges</item>
</div>
|
| Elapsed Time (ms) | 32 |