Получить наиболее повторяющийся элемент в последовательности с XQuery - PullRequest
6 голосов
/ 24 июня 2010

У меня есть последовательность значений.Все они могут быть равны ... или нет.Так что с 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 {} 

Я не могу сделать эту работу, поэтому я полагаю, что я делаю что-то не так.

Заранее спасибо за любую помощь, которую вы могли бы мне оказать.

Ответы [ 2 ]

6 голосов
/ 24 июня 2010

Использование :

  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]

Обновление, декабрь 2015 :

Это значительно короче, хотя может и не бытьслишком эффективный:

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

Самое короткое выражение может быть построено для XPath 3.1:

enter image description here

И даже короче и копируемый - используя односимвольное имя:

$s[index-of($s,.)[max($s ! count(index-of($s, .)))]]
1 голос
/ 24 июня 2010

Вы подходите к этой проблеме с чрезмерной точки зрения.

В XQuery вы можете установить значения переменных, но вы никогда не сможете их изменить.

Правильный способ выполнения алгоритмов итеративного типа - с помощью рекурсивной функции:

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)
}

но лучший способ решения проблемы - это описание проблемы не итерационным способом. В этом случае для всех различных значений в вашей последовательности вы хотите, чтобы значение, которое появляется максимальное количество раз для любого отдельного значения.

Предыдущая отправка, переведенная в XQuery:

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
...