从列表中计算增量

时间:2011-09-01 09:20:45

标签: algorithm functional-programming xquery

我有这个清单:

  • ADD X
  • ADD Y
  • 删除Z
  • ADD X
  • NO ACTION Y

我需要这个结果:

  • ADD X
  • NO ACTION Y
  • 删除Z

计算三角洲的规则如下: 我有3个动作(ADD,REMOVE,NO ACTION)

  1. 任何行动*无行动=无行动
  2. ADD * REMOVE或REMOVE * ADD = NO ACTION
  3. 同样行动*同样行动=同样行动
  4. 问题在于我使用函数式语言(XQuery)实现了这一点。我找到了一个基于fn:distinct-values的逻辑。但最后一条规则(3)并不令人满意。

    提前致谢!!

2 个答案:

答案 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
 };

简单但有效。

非常感谢所有人!