2010-06-24 25 views
6

Tengo una secuencia de valores. Todos pueden ser iguales ... o no. Entonces, con XQuery, quiero obtener el elemento más frecuente en la secuencia.Obtiene el elemento más repetido en una secuencia con XQuery

let $counter := 0, $index1 := 0 
for $value in $sequence 
if (count(index-of($value, $sequence))) 
then 
{ 
$counter := count(index-of($value, $sequence)) $index1 := index-of($value) 
} else {} 

No puedo hacer que esto funcione, por lo que supongo que estoy haciendo algo mal.

Gracias de antemano por cualquier ayuda que pueda darme.

+0

Buena pregunta nuevamente (+1). Y la respuesta es una expresión de una línea de XPath ... intentará hacerlo aún más corto. –

Respuesta

6

Uso:

for $maxFreq in 
      max(for $val in distinct-values($sequence) 
        return count(index-of($sequence, $val)) 
       ) 
    return 
     distinct-values($sequence)[count(index-of($sequence, .)) eq $maxFreq] 

actualización, Dic el año 2015:

Esto es notablemente más corto, aunque puede que no sea demasiado Eficiente:

$pSeq[index-of($pSeq,.)[max(for $item in $pSeq return count(index-of($pSeq,$item)))]] 

La expresión más corto puede ser construido para XPath 3.1:

enter image description here

Y aún más corto y copiable - el uso de un nombre de un carácter:

$s[index-of($s,.)[max($s ! count(index-of($s, .)))]] 
+0

Muchas gracias, creo que mi inexperiencia me ha llevado a intentar un enfoque muy retorcido. – deb

1

Se está acercando a este problema desde un punto de vista imperativo.

En XQuery puede establecer los valores de las variables, pero nunca puede cambiarlas.

La forma correcta de hacer algoritmos de tipo iterativo es con una función recursiva:

declare funciton local:most($sequence, $index, $value, $count) 
{ 
    let $current=$sequence[$index] 
    return 
    if (empty($current)) 
    then $value 
    else 
     let $current-count = count(index-of($current, $sequence)) 
     return 
     if ($current-count > $count) 
     then local:most($sequence, $index+1, $current, $current-count) 
     else local:most($sequence, $index+1, $value, $count) 
} 

pero una mejor manera de abordar el problema es mediante la descripción del problema de una manera no iterativo. En este caso, de todos los valores distintos en su secuencia, quiere el que aparece el número máximo de veces de cualquier valor distinto.

La frase o comentario anterior traducido en XQuery es

let $max-count := max(for $value1 in distinct-values($sequence) 
         return count(index-of($sequence, $value1))) 
for $value2 in distinct-values($sequence) 
where (count(index-of($sequence, $value2)) = $max-count 
return $value2 
+0

Muchas gracias, intenté tu camino y también funciona. – deb

Cuestiones relacionadas