Как передать сложную лямбда-функцию серверу gremlin с помощью Java API?

Пытаюсь пройти график с интервалом. Каждое ребро имеет свойство (интервал), в котором хранятся интервалы. Я использую 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

Если я начну обход из V1 с интервалом [2,8], я хочу, чтобы он вернул

V1: [[2,3],[5,7]]
V2: [[5,6]]

Обратите внимание, что V3 и V4 не включены, поскольку интервал пересечения на e2 заканчивается на 6.

Я использую Tinkerpop Java API и для этой цели я определил метод, который возвращает пересечения интервалов, и попытался использовать 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;
}

У меня 2 вопроса:

  1. Как передать такую ​​сложную лямбда-функцию серверу gremlin?
  2. Есть ли лучший способ добиться этого?

person Alpha Carinae    schedule 10.05.2021    source источник


Ответы (1)


Строка лямбда-выражения должна соответствовать форме закрытия Groovy. Для многострочного сценария и сценария с несколькими аргументами вам нужно обернуть его фигурными скобками:

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 (надеюсь, правильно), что в итоге получилось немного более лаконичным, но эта часть не должна быть необходимой.

person stephen mallette    schedule 11.05.2021
comment
Благодарю за ваш ответ. У меня такое же исключение: expecting '}', found 'if' @ line 1, column 158. x, y -> intersections = [] if (x.isEm. Однако я написал ту же функцию в отличный файл сценария, который инициализируется ScriptFileGremlinPlugin при запуске сервера. Затем я смог вызвать функцию в своем запросе. - person Alpha Carinae; 11.05.2021
comment
о ... я избавился от точки с запятой, но не добавил перевод строки. обновленный ответ. может быть, это исправит. это что-то простое. просто синтаксическая ошибка в отличной оценке. - person stephen mallette; 11.05.2021