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
顺便问个好问题。
我正在尝试做一些应该非常简单的事情。我有一个包含 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
顺便问个好问题。