Tinkerpop Gremlin - 如何简化 2 计数数组上的 {a - b} 数学?

Tinkerpop Gremlin - How to simplify {a - b} maths on a 2 count array?

我正在尝试做一些应该非常简单的事情。我有一个包含 2 个边的数组流。对于每个数组,我只想从第一个边的第二个边上减去一个值。在某些语言中,这只是 array[0].value - array[1].value。但是,我只能通过以下操作实现这一目标:

local(
    project('a', 'b').
      by(unfold().limit(1)).
      by(unfold().tail(1)).
    math('a - b').
      by('bias'))

这行得通,但是如果没有 project()limit()tail(),这似乎应该更简单。这也让我质疑如果数组中有 3 个或更多项,我将如何从数组中获取正确的项。例如。如果它不再是 tail(),我将如何获得第二个项目?我猜limit(2).tail(1)?它看起来非常混乱。如果我简单地使用 fold() 步骤,我可以非常接近于简化这个操作:

local(
    unfold().
    values('bias').
    fold(0, minus))

以这种方式使用 fold() 非常干净,但是会导致 0 - a - b。如果我可以用动态值替换该种子,那么我可以获得更多。但即便如此,我也必须执行类似 (2 * a) - a - b 的操作才能获得正确的结果。尝试用 limit(1).values('bias') 等动态变量替换 0 种子失败,因为它是错误的类型。但无论如何我都不会满足于这样的任意代码。然后我最后的想法是通过索引 select 索引项目:

local(
    index().
      with(WithOptions.indexer, WithOptions.map))

虽然边缘的索引很好,但我找不到使它有用的方法。我以为我可以 select('0') 得到第一个项目,但没有返回任何东西。

我想我的问题如下: 有没有一种简单的方法可以像使用 sum()fold(0, sum) 实现 a + b 一样简单地实现 a - b? 如果没有,是否有更简洁的方法来选择数组中的项目进行数学运算?还是应该在数学之前将所有内容通常放在 project() 中?就是显得太麻烦了...

您可以轻松跳过 project()

gremlin> arr = [[g.E(7).next(),g.E(8).next()],[g.E(8).next(),g.E(10).next()]]
==>[e[7][1-knows->2],e[8][1-knows->4]]
==>[e[8][1-knows->4],e[10][4-created->5]]
gremlin> g.inject(arr).unfold().as('a','b').
......1>   math('a - b').
......2>     by(limit(local,1).values('weight')).
......3>     by(tail(local,1).values('weight'))
==>-0.5
==>0.0

您仍然需要 unfold().limit()/tail(),但我认为这是一种更好的方法,因为它避免了创建 Map 只是为了将其丢弃。

It also makes me question how I would get the correct item from an array if there were 3 or more items in there. Eg. how would I get the second item if it's no longer the tail()? I guess limit(2).tail(1)?

您可以使用 range() 来避免多步骤方法:

gremlin> arr = [[g.E(7).next(),g.E(8).next(),g.E(9).next()],[g.E(8).next(),g.E(10).next(),g.E(10).next()]]
==>[e[7][1-knows->2],e[8][1-knows->4],e[9][1-created->3]]
==>[e[8][1-knows->4],e[10][4-created->5],e[10][4-created->5]]
gremlin> g.inject(arr).unfold().as('a','b').
......1>   math('a - b').
......2>     by(limit(local,1).values('weight')).
......3>     by(range(local,1,2).values('weight'))
==>-0.5
==>0.0

你可以使用 sack() 来避免 math() 但我不确定它是否简化了你内部列表的分离(即你仍然坚持使用 limit()/tail()):

gremlin> arr = [[g.E(7).next(),g.E(8).next()],[g.E(8).next(),g.E(10).next()]]
==>[e[7][1-knows->2],e[8][1-knows->4]]
==>[e[8][1-knows->4],e[10][4-created->5]]
gremlin> g.withSack(0).inject(arr).unfold().
......1>   sack(assign).by(limit(local,1).values('weight')).
......2>   sack(minus).by(tail(local,1).values('weight')).
......3>   sack()
==>-0.5
==>0.0

顺便问个好问题。