Given a list of objects, what's the best way to generate all possible pairs?
Code I've tried:
g.inject(1, 2, 3).project('a', 'b').by().by()
Expected:
[
{'a': 1, 'b': 1},
{'a': 1, 'b': 2},
{'a': 1, 'b': 3},
{'a': 2, 'b': 1},
{'a': 2, 'b': 2},
{'a': 2, 'b': 3},
{'a': 3, 'b': 1},
{'a': 3, 'b': 2},
{'a': 3, 'b': 3},
]
Actual:
[
{'a': 1, 'b': 1},
{'a': 2, 'b': 2},
{'a': 3, 'b': 3},
]
Here's the first approach that came to mind for me - wouldn't be surprised if there was a more direct way to think about this, but:
gremlin> g.inject([1,2,3]).as('x').
......1> unfold().as('a').
......2> map(select('x').
......3> unfold().
......4> project('a','b').
......5> by(select('a')).
......6> by().
......7> fold()).
......8> unfold()
==>[a:1,b:1]
==>[a:1,b:2]
==>[a:1,b:3]
==>[a:2,b:1]
==>[a:2,b:2]
==>[a:2,b:3]
==>[a:3,b:1]
==>[a:3,b:2]
==>[a:3,b:3]
I guess the "trick" in this approach is to iterate "x" (i.e. the list of numbers) twice, once for "a" and once for "b". Perhaps the looping semantics could be better understood in a repeat()
context:
gremlin> g.inject([1,2,3]).as('x').
......1> unfold().as('a').
......2> repeat(select('x').
......3> unfold().
......4> project('a','b').
......5> by(select('a')).
......6> by()).
......7> times(1)
==>[a:1,b:1]
==>[a:1,b:2]
==>[a:1,b:3]
==>[a:2,b:1]
==>[a:2,b:2]
==>[a:2,b:3]
==>[a:3,b:1]
==>[a:3,b:2]
==>[a:3,b:3]
Not sure if that same intent is more clear with that approach or not. I think I prefer the former. As I finished typing that I realized all of this could simplify down to:
gremlin> g.inject([1,2,3]).as('x').
......1> unfold().as('a').
......2> select('x').
......3> unfold().as('b').
......4> select('a','b')
==>[a:1,b:1]
==>[a:1,b:2]
==>[a:1,b:3]
==>[a:2,b:1]
==>[a:2,b:2]
==>[a:2,b:3]
==>[a:3,b:1]
==>[a:3,b:2]
==>[a:3,b:3]
Obviously, I'd say this last solution is the best and easiest to read.