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

Gremlin 小精灵-如何简化2计数数组上的{a-b}数学?,gremlin,tinkerpop,Gremlin,Tinkerpop,我正在尝试做一些应该很简单的事情。我有一个包含两条边的数组流。对于每个数组,我只想从第一条边减去第二条边上的值。在某些语言中,这可能只是array[0]。value-array[1]。value。然而,我仅通过以下方式实现了这一目标: local( project('a', 'b'). by(unfold().limit(1)). by(unfold().tail(1)). math('a - b'). by('bias')) 这是可行的,但

我正在尝试做一些应该很简单的事情。我有一个包含两条边的数组流。对于每个数组,我只想从第一条边减去第二条边上的值。在某些语言中,这可能只是
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()
,我将如何获得它?我猜
极限(2)。尾部(1)
?看起来非常混乱。如果我简单地使用
fold()
步骤,我可以非常接近于简化此操作:

local(
    unfold().
    values('bias').
    fold(0, minus))
以这种方式使用
fold()
非常干净,但是会导致
0-a-b
。如果我可以用一个动态的值来替换这个种子,那么我可以获得更多。但即使这样,我也必须做一些类似于
(2*a)-a-b
,以获得正确的结果。尝试将
0
种子替换为动态变量,如
limit(1)。值('bias')
由于类型错误而失败。但无论如何,我都不会满足于这样的任意代码。然后,我最后的想法是为项目编制索引,然后按索引进行选择:

local(
    index().
      with(WithOptions.indexer, WithOptions.map))
虽然边的索引很好,但我找不到一种方法使其有用。我想我可以
选择('0')
来获取第一项,但是没有返回任何内容

我想我的问题如下: 是否有一种简单的方法可以实现
a-b
,就像
a+b
是通过
sum()或
fold(0,sum)
实现的一样? 如果没有,是否有更干净的方法来选择数学数组中的项目?还是应该在数学之前把所有的东西都放进
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()
,但我认为这是一种更好的方法,因为它可以避免创建一个
映射图而将其扔掉

这也让我质疑,如果数组中有3个或更多项,如何从数组中获取正确的项。如果第二项不再是尾部,我怎么才能得到它呢?我猜是极限(2)。尾巴(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()
,但我不确定它是否简化了内部列表的分类(即您仍然坚持
限制()
/
尾部()
):


顺便提一下,这是个好问题。

方法很棒。到目前为止,我甚至从未想过使用带有两个字符串的
as()
。当我们讨论这个主题时,有没有办法在
index()
之后分离数组?与使用映射选项进行索引和选择例如索引2一样,任何列表/数组都可以使用
unfold()
展平为流,或者使用
range()
定向步骤使用
local
范围进行拆分。如果这还不清楚,或者如果我误解了,也许可以提出一个新问题,我可以试着更完整地回答。当我做出这样的回答时,我正在考虑挑选一张地图。但现在我想得更清楚了,不仅不需要地图,而且还可以使用
select(values)
将地图展平为其值。你说得对。再次感谢。
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