Как выполнить итерацию функции многовалентного ранга (> 1), например f:{[x;y] ...} где входные данные функции на следующем шаге итерации зависят от последнего шага итерации? Примеры в справочном руководстве повторяют только унарные функции.

Я смог достичь этого косвенно (и многословно), передав словарь аргументов (состояние) в унарную функцию:

f:{[arg] key[arg]!(min arg;arg[`y]-2)}                                                          
f/[{0<x`x};`x`y!6 3]

Обратите внимание, что проекция, например, f[x;]/[whilecond;y] будет работать только в сценарии, где x на следующем шаге итерации не зависит от результата последней итерации (т. Е. Когда х не зависит от пути).

kdb
2
Daniel Krizian 1 Янв 2019 в 20:07

3 ответа

Лучший ответ

Что касается ответа Рахула, вы можете использовать один из следующих (чуть менее многословных) методов для достижения того же результата:

q)g:{(min x,y;y-2)}
q)(g .)/[{0<x 0};6 3]
-1 -3
q).[g]/[{0<x 0};6 3]
-1 -3

В качестве альтернативы вы можете использовать функцию .z.s self, которая рекурсивно вызывает функцию g и принимает выходные данные последней итерации в качестве аргументов. Например,

q)g:{[x;y] x: min x,y; y:y-2; $[x<0; (x;y); .z.s[x;y]]}
q)g[6;3]
-1 -3
2
Daniel Krizian 2 Янв 2019 в 16:21

Функция, которая используется с '/' и '\', может принимать только результат последней итерации как один элемент, что означает, что для результата зарезервирован только 1 параметр функции. Это унарный в этом смысле.

Для функции, множественные входные параметры которой зависят от результата последней итерации, одним из решений является обертывание этой функции внутри унарной функции и использование оператора apply для выполнения этой функции в результате последней итерации.

Пример:

      q) g:{(min x,y;y-2)}  / function with rank 2
      q) f:{x . y}[g;]   / function g wrapped inside unary function to iterate
      q) f/[{0<x 0};6 3]
1
Rahul 1 Янв 2019 в 22:44

Со временем я наткнулся на еще более короткий путь, который не требует скобок или скобок:

q)g:{(min x,y;y-2)}
q){0<x 0} g//6 3
-1 -3

Почему двойной over (//) работает? Иногда наречие / можно использовать вместо оператора . (apply):

q)(*) . 2 3
6
q)(*/) 2 3
6
0
Daniel Krizian 10 Апр 2020 в 22:38