使用 XQuery 计算序列中的连续重复元素

Count consecutive repetitive element in a sequence using XQuery

如果序列 = [a a b c c c a d d e e e f g h h]

然后输出 = [1 2 1 1 2 3 1 1 2 1 2 3 1 1 1 2]

已尝试使用递归但没有成功...请帮助...感谢期待

注意:使用 XQuery 实现 1.0

我失败的实施之一如下所示:

declare function local:test($sequence,$count){

for $counter in (1 to count($sequence))

let $maxIndex := count($sequence)

return

if (matches(subsequence($sequence,1,$maxIndex)[$counter],subsequence($sequence,1,$maxIndex)[$counter + +1])) then let $count := $count + 1 return $count[last()]

else let $count := 1 return $count[last()]


};

你是对的,递归是一种非常可行的方法。以下函数的作用是从头到尾遍历序列。对于每个元素,它然后在 local:count() 中计算之前的元素是否与当前元素相同。如果是,则递归调用该函数,否则重复序列结束,返回1。

最后,这个生成的序列再次反转以匹配传入序列的顺序。

declare function local:count($sequence, $pos) {
  if ($sequence[$pos - 1] = $sequence[$pos])
  then 1 + local:count($sequence, $pos - 1)
  else 1
};

declare function local:test($sequence){
  reverse(
    for $pos in reverse(1 to count($sequence))
    return local:count($sequence, $pos)
  )
};

let $test := ("a","a", "b", "c", "c", "c", "a", "d", "d", "e", "e", "e", "f", "g", "h", "h")
return local:test($test)

我的问题得到了有效的解决方案。学分:odie_63@http://odieweblog.wordpress.com/

declare namespace xf = "http://tempuri.org/OSBTestProject/Resources/XQuery/test/";

declare function local:sequence-group($seq as item()*) as item()*
{
   let $start-of-group :=
   fn:index-of(
     for $i in 1 to count($seq)
     let $prev := $seq[$i - 1]
     return if ($prev != $seq[$i] or not($prev)) then 1 else 0
   , 1
   )
   return
     for $i in 1 to count($seq)
     return $i - $start-of-group[. le $i][last()] + 1
};

declare function xf:test($test as xs:string) as xs:integer*
 {
let $test1 := tokenize($test, ',')
 return  local:sequence-group($test1)
};

declare variable $test as xs:string external;

xf:test($test)

输入:a,a,b,c,c,c,a,d,d,e,e,e,f,g,h,h

输出:1 2 1 1 2 3 1 1 2 1 2 3 1 1 1 2

未测试,但这应该有效,而且相当简单。

declare function local:test($sequence)
{
    for $item at $current-pos in $sequence
    let $different-pos :=
        last((0, $sequence[position() < $current-pos][. != $item]))
    return $current-pos - $different-pos
}