从列表中计算增量

发布于 2024-12-02 05:14:37 字数 416 浏览 0 评论 0原文

我有这个列表:

  • ADD X
  • ADD Y
  • REMOVE Z
  • ADD X
  • NO ACTION Y

我需要这个结果:

  • ADD X
  • NO ACTION Y
  • REMOVE Z

计算增量的规则如下: 我有 3 个操作(添加、删除、无操作)

  1. 任何操作*无操作=无操作
  2. 添加*删除或删除*添加=无操作
  3. 相同操作*相同操作=相同操作

问题是我用函数式语言实现此操作( X 查询)。我找到了一个基于 fn:distinct-values 的逻辑。但最后一条规则(3)不满足。

提前致谢!!

I have this list:

  • ADD X
  • ADD Y
  • REMOVE Z
  • ADD X
  • NO ACTION Y

I need of this results:

  • ADD X
  • NO ACTION Y
  • REMOVE Z

The rules to calculate the delta are these:
I have 3 action (ADD, REMOVE, NO ACTION)

  1. ANY ACTION * NO ACTION = NO ACTION
  2. ADD * REMOVE or REMOVE * ADD = NO ACTION
  3. SAME ACTION * SAME ACTION = SAME ACTION

The problem is that I implement this with a functional language (XQuery). I found a logic, based on fn:distinct-values. But the last rule (3) is unsatisfied.

Thanks in advance!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

陈独秀 2024-12-09 05:14:37

您没有提到您正在使用什么 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” " 使解析更简单。

You didn't mention what XQuery processor you are using, but if it has hashmaps, you can do it this way (tested in 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)

Returns

ADD X 
REMOVE Z 
NO-ACTION Y

Note that I made a simplifying assumption and changed "NO ACTION" to "NO-ACTION" to make the parsing simpler.

嘦怹 2024-12-09 05:14:37

终于我找到了路。我希望这是好的。

这是我对 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. else 如果存在几乎 ONE - NO ACTION ->不采取任何行动(规则 1)
2. else 如果同一列表中存在 ADD 和 REMOVE ->不采取行动(规则 2)
3. else 采取第一个动作(相等的动作)

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

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

简单但有效。

非常感谢大家!

Finally I found the way. I hope that this is good.

These are my first experiments with XQuery and I need to remeber what I have under my fingers and what possibilities this language offer.

My problem is data that came in. And I decide to transformate the information in a structure that can I easily manipulate.

A golden brick to solve this is this example about grouping data :

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>

After this I used this algorithm:
0. If the count of action == 1 -> take first action
1. else If exist almost ONE - NO ACTION -> NO ACTION (RULE 1)
2. else If exist ADD and REMOVE in same list -> NO ACTION (RULE 2)
3. else take the first action (equal actions)

For this I borrowed a function from functx library:

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

Simple but effective.

Thanks a lot for all!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文