Я пытаюсь перебирать элементы и выводить количество вхождений для каждого из них, но он выводит один и тот же словарь количество раз, равное количеству элементов. Есть ли способ, аналогичный использованию скобок, чтобы просто сделать циклы для операторов let
. Я знаю, что XQuery — это функциональный язык и что я могу использовать group by
, но он не поддерживается в marklogic.
xquery version "1.0-ml";
let $dict := map:map()
for $i in ('book1','book2','book2')
let $n := (if (map:contains($dict, $i)) then (map:get($dict, $i)) else (0))
let $dict1 := map:put($dict, $i, 1 + $n)
return $dict
Выход:
<map:map>
<map:entry key = "book1">
<map:value xsi:type = "xs:integer">1</map:value>
</map:entry>
<map:entry key = "book2">
<map:value xsi:type = "xs:integer">2</map:value>
</map:entry>
</map:map>
map as
XML
<map:map>
<map:entry key = "book1">
<map:value xsi:type = "xs:integer">1</map:value>
</map:entry>
<map:entry key = "book2">
<map:value xsi:type = "xs:integer">2</map:value>
</map:entry>
</map:map>
map as
XML
<map:map>
<map:entry key = "book1">
<map:value xsi:type = "xs:integer">1</map:value>
</map:entry>
<map:entry key = "book2">
<map:value xsi:type = "xs:integer">2</map:value>
</map:entry>
</map:map>
Вы можете let
одноразовую переменную, а затем выполнить обработку FLWOR цикла for для этой переменной, а затем вернуть $dict
карту:
xquery version "1.0-ml";
let $dict := map:map()
let $_ :=
for $i in ('book1','book2','book2')
let $n := if (map:contains($dict, $i)) then map:get($dict, $i) else 0
return map:put($dict, $i, 1 + $n)
return $dict
Поскольку map:put()
возвращает пустую последовательность, вы также можете вернуть последовательность с обработкой цикла for, а затем $dict
:
xquery version "1.0-ml";
let $dict := map:map()
return (
for $i in ('book1','book2','book2')
let $n := if (map:contains($dict, $i)) then map:get($dict, $i) else 0
return map:put($dict, $i, 1 + $n),
$dict
)
Более сжатая версия той же обработки:
xquery version "1.0-ml";
let $dict := map:map()
let $_ := ('book1','book2','book2') ! map:put($dict, ., 1 + head((map:get($dict, .), 0)))
return $dict
В дополнение к ответу @MadsHansen вы также можете использовать дополнительные функции:
xquery version "1.0-ml";
let $dict := map:map()
let $myvalues := ('book1','book2','book2')
let $_ :=
for $i in fn:distinct-values($myvalues)
return map:put($dict, $i, count(index-of($i, $myvalues)))
return $dict
(Я выбрал функцию «частота» с комбинацией count
и index-of
из другой ответ о переполнении стека)