如何使用 Java API 将复杂的 lambda 函数传递给 gremlin 服务器?
How to pass a complex lambda function to gremlin server by using Java API?
我正在尝试以一定间隔遍历图表。每条边都有一个 属性("interval") 存储间隔。我正在使用 withSack
将间隔的交集传播到下一步。如果没有交集,遍历应该停止。
例如:
V1 e1 V2 e2 V3 e3 V4
O----------------------O----------------------O----------------------O
^
[[1,3],[5,7]] [[4,6]] [[7,9]]
e1.interval e2.interval e3.interval
如果我从区间[2,8]的V1开始遍历,我希望它return
V1: [[2,3],[5,7]]
V2: [[5,6]]
注意不包括 V3 和 V4,因为 e2 上的相交区间停止在 6。
我正在使用 Tinkerpop Java API 并且为此目的,我定义了一个 return 间隔交集的方法并尝试使用 withSack(Lambda.biFunction(...))
.该函数有一个带花括号的 while 循环({}
),我认为它会导致 gremlin 服务器的脚本引擎出现问题。我得到的例外是:
Script28.groovy: 1: expecting '}', found 'return' @ line 1, column 520.
get(j).get(1)) i++; else j++;}return int
我将函数作为字符串传递给 (Lambda.biFunction(...))
,如下所示:
"x, y -> " +
"List<List<Long>> intersections = new ArrayList();" +
"if (x.isEmpty() || y.isEmpty()) return new ArrayList<>();" +
"int i = 0, j = 0;" +
"while (i < x.size() && j < y.size()) {" +
"long low = Math.max(x.get(i).get(0), y.get(j).get(0));" +
"long high = Math.min(x.get(i).get(1), y.get(j).get(1));" +
"if (low <= high) intersections.add(Arrays.asList(low, high));" +
"if (x.get(i).get(1) < y.get(j).get(1)) i++; else j++;" +
"}" +
"return intersections;";
为了可读性,我也把原来的功能:
public List<List<Long>> intersections(List<List<Long>> x, List<List<Long>> y) {
List<List<Long>> intersections = new ArrayList();
if (x.isEmpty() || y.isEmpty()) {
return new ArrayList<>();
}
int i = 0, j = 0;
while (i < x.size() && j < y.size()) {
long low = Math.max(x.get(i).get(0), y.get(j).get(0));
long high = Math.min(x.get(i).get(1), y.get(j).get(1));
if (low <= high) {
intersections.add(Arrays.asList(low, high));
}
if (x.get(i).get(1) < y.get(j).get(1)) {
i++;
} else {
j++;
}
}
return intersections;
}
我有两个问题:
- 如何将这样一个复杂的 lambda 函数传递给 gremlin 服务器?
- 有没有更好的方法来完成这个?
您的 lambda 字符串需要匹配 Groovy closure form。对于你的多行和多参数脚本,你需要用大括号括起来:
withSack(Lambda.biFunction(
"{ x, y -> " +
" intersections = []\n" +
" if (x.isEmpty() || y.isEmpty()) return []\n" +
" i = 0\n" +
" j = 0\n" +
" while (i < x.size() && j < y.size()) {\n" +
" def low = Math.max(x[i][0], y[j][0])\n" +
" def high = Math.min(x[i][1], y[j][1])\n" +
" if (low <= high) intersections.add(Arrays.asList(low, high))\n" +
" if (x[i][1] < y[j][1]) i++; else j++\n" +
" }\n" +
" return intersections\n" +
"}"))
我还将您的 Java 转换为 Groovy(希望是正确的),最终会更简洁一些,但那部分应该是不必要的。
我正在尝试以一定间隔遍历图表。每条边都有一个 属性("interval") 存储间隔。我正在使用 withSack
将间隔的交集传播到下一步。如果没有交集,遍历应该停止。
例如:
V1 e1 V2 e2 V3 e3 V4
O----------------------O----------------------O----------------------O
^
[[1,3],[5,7]] [[4,6]] [[7,9]]
e1.interval e2.interval e3.interval
如果我从区间[2,8]的V1开始遍历,我希望它return
V1: [[2,3],[5,7]]
V2: [[5,6]]
注意不包括 V3 和 V4,因为 e2 上的相交区间停止在 6。
我正在使用 Tinkerpop Java API 并且为此目的,我定义了一个 return 间隔交集的方法并尝试使用 withSack(Lambda.biFunction(...))
.该函数有一个带花括号的 while 循环({}
),我认为它会导致 gremlin 服务器的脚本引擎出现问题。我得到的例外是:
Script28.groovy: 1: expecting '}', found 'return' @ line 1, column 520.
get(j).get(1)) i++; else j++;}return int
我将函数作为字符串传递给 (Lambda.biFunction(...))
,如下所示:
"x, y -> " +
"List<List<Long>> intersections = new ArrayList();" +
"if (x.isEmpty() || y.isEmpty()) return new ArrayList<>();" +
"int i = 0, j = 0;" +
"while (i < x.size() && j < y.size()) {" +
"long low = Math.max(x.get(i).get(0), y.get(j).get(0));" +
"long high = Math.min(x.get(i).get(1), y.get(j).get(1));" +
"if (low <= high) intersections.add(Arrays.asList(low, high));" +
"if (x.get(i).get(1) < y.get(j).get(1)) i++; else j++;" +
"}" +
"return intersections;";
为了可读性,我也把原来的功能:
public List<List<Long>> intersections(List<List<Long>> x, List<List<Long>> y) {
List<List<Long>> intersections = new ArrayList();
if (x.isEmpty() || y.isEmpty()) {
return new ArrayList<>();
}
int i = 0, j = 0;
while (i < x.size() && j < y.size()) {
long low = Math.max(x.get(i).get(0), y.get(j).get(0));
long high = Math.min(x.get(i).get(1), y.get(j).get(1));
if (low <= high) {
intersections.add(Arrays.asList(low, high));
}
if (x.get(i).get(1) < y.get(j).get(1)) {
i++;
} else {
j++;
}
}
return intersections;
}
我有两个问题:
- 如何将这样一个复杂的 lambda 函数传递给 gremlin 服务器?
- 有没有更好的方法来完成这个?
您的 lambda 字符串需要匹配 Groovy closure form。对于你的多行和多参数脚本,你需要用大括号括起来:
withSack(Lambda.biFunction(
"{ x, y -> " +
" intersections = []\n" +
" if (x.isEmpty() || y.isEmpty()) return []\n" +
" i = 0\n" +
" j = 0\n" +
" while (i < x.size() && j < y.size()) {\n" +
" def low = Math.max(x[i][0], y[j][0])\n" +
" def high = Math.min(x[i][1], y[j][1])\n" +
" if (low <= high) intersections.add(Arrays.asList(low, high))\n" +
" if (x[i][1] < y[j][1]) i++; else j++\n" +
" }\n" +
" return intersections\n" +
"}"))
我还将您的 Java 转换为 Groovy(希望是正确的),最终会更简洁一些,但那部分应该是不必要的。