2011-09-01 79 views
0

增量我有这样的名单:计算从列表

  • 添加X
  • 加上y
  • REMOVEž
  • 添加X
  • NO动作Y

我需要的结果:

  • ADD X
  • NO动作Y
  • REMOVEŽ

计算增量的规则是这些: 我有3个动作(添加,删除,无动作)

  1. 任何行动*无行动=无行动
  2. ADD * REMOVE或REMOVE * ADD = NO ACTION
  3. SAME A CTION * SAME ACTION = SAME Action

问题是我使用函数式语言(XQuery)实现了这一点。我发现了一个基于fn:distinct-values的逻辑。但最后一条规则(3)不满意。

在此先感谢!

+0

是否按顺序处理输入列表? – Svante

+0

不是。该列表来自xml。 –

+0

对不起,但你不明白我在问什么。结果似乎取决于输入元素的顺序。 – Svante

回答

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的计数 - >采取第一动作 1。否则如果存在差不多一个 - 没有行动 - >没有行动(规则1) 2. else如果在同一列表中存在ADD和REMOVE - > NO ACTION(RULE 2) 3。否则采取的第一个动作(等于动作)

为此,我借了functx库中的函数:

declare function local:is-value-in-sequence($value as xs:anyAtomicType? ,$seq as  xs:anyAtomicType*) as xs:boolean { 
$value = $seq 
}; 

简单而有效。

非常感谢大家!

2

你没有提到你使用的XQuery处理,但是如果它有包含HashMap,你可以做这样(在M​​arkLogic服务器测试):

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”,以使解析更简单。

+0

不幸的是Saxon-EE 9.2.0.3 –