问题描述
我正在尝试做一些应该很简单的事情。我有一个包含 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
的操作才能获得正确的结果。尝试用动态变量(例如 0
)替换 limit(1).values('bias')
种子失败,因为它的类型错误。但无论如何,我不会对这种任意代码感到满意。然后我最后的想法是索引项目然后按索引选择:
local(
index().
with(WithOptions.indexer,WithOptions.map))
虽然边缘的索引很好,但我找不到一种方法来使它有用。我以为我可以 select('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()
,但我认为这是一种更好的方法,因为它避免了创建 Map
只是为了将其丢弃。
这也让我怀疑,如果数组中有 3 个或更多项,我将如何从数组中获取正确的项。例如。如果它不再是 tail(),我将如何获得第二项?我猜是limit(2).tail(1)?
您可以使用 range()
来避免多步骤方法:
gremlin> arr = [[g.E(7).next(),g.E(8).next(),g.E(9).next()],g.E(10).next(),e[8][1-knows->4],e[9][1-created->3]]
==>[e[8][1-knows->4],e[10][4-created->5],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(),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
顺便提一下好问题。