我有这个清单:
我需要这个结果:
计算三角洲的规则如下: 我有3个动作(ADD,REMOVE,NO ACTION)
问题在于我使用函数式语言(XQuery)实现了这一点。我找到了一个基于fn:distinct-values的逻辑。但最后一条规则(3)并不令人满意。
提前致谢!!
答案 0 :(得分:2)
您没有提到您正在使用的XQuery处理器,但如果它有哈希映射,您可以这样做(在MarkLogic Server中测试):
let $seq := ("ADD X", "ADD Y", "REMOVE Z", "ADD X", "NO-ACTION Y")
let $map := map:map()
let $_ :=
for $s in $seq
let $parts := fn:tokenize($s, " ")
let $service := $parts[2]
let $action := $parts[1]
let $current-action := map:get($map, $service)
return
if ("NO-ACTION" = ($action, $current-action)) then
map:put($map, $service, "NO-ACTION") (: rule 1 :)
else if ("REMOVE" = ($action, $current-action)) then
map:put($map, $service, "REMOVE") (: rule 2 :)
else
map:put($map, $service, $action) (: actions are the same -- rule 3 :)
for $service in map:keys($map)
return fn:concat(map:get($map, $service), " ", $service)
返回
ADD X
REMOVE Z
NO-ACTION Y
请注意,我做了一个简化的假设并将“NO ACTION”更改为“NO-ACTION”以使解析更简单。
答案 1 :(得分:0)
最后我找到了方法。我希望这很好。
这是我第一次使用XQuery进行的实验,我需要记住手指下的内容以及这种语言提供的可能性。
我的问题是进来的数据。我决定将信息转换为可以轻松操作的结构中的信息。
解决这个问题的一个金砖就是这个关于数据分组的例子:
for $d in distinct-values(doc("order.xml")//item/@dept)
let $items := doc("order.xml")//item[@dept = $d]
order by $d
return <department code="{$d}">{
for $i in $items
order by $i/@num
return $i
}</department>
在此之后我使用了这个算法: 0.如果行动计数== 1 - &gt;采取第一行动 1.如果存在几乎一个 - 没有行动 - &gt;无动作(规则1) 2.否如果在同一列表中存在ADD和REMOVE - &gt;无行动(规则2) 3.否则采取第一个行动(平等行动)
为此,我从functx库中借用了一个函数:
declare function local:is-value-in-sequence( $value as xs:anyAtomicType? ,$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
};
简单但有效。
非常感谢所有人!