2022.04.19 04:22 AM
hi suppose i have a column named Id and PrevId. Understand it is trying to find original Id for each row but still not sure how it works exactly.
update originalId:{x1:y x;$[ =x1;x;.z.s[x1;y]]} [; Id!PrevId] each Id from table`
2022.04.19 06:59 AM
Couple of syntax errors above, but let’s break down what we can. The trailing backtick was probably you trying to use Markdown for the expression; we can ignore that.
The query defines a new column OriginalId
by applying a lambda to each ID. The lambda is projected on (curried to) its second argument. That is, within the lambda y
refers to Id!PrevId
, which is a dictionary mapping IDs to previous IDs. The lambda has two expressions. The first expression applies y
(the dictionary) to x
(the ID) to get the previous ID, x1
. The second expression is a ternary conditional, Cond. This tests x1
and here is your second syntax error: the comparison term is missing. I strongly suspect it should be x
. That is, if x=x1
, if the previous ID is the same as this ID, then return it as the result. Otherwise apply .z.s
to x1
and y
. Now .z.s
is a reference to the current function, so this is a recursion; it ends when the ‘previous’ ID is just the ID.
There is a simpler way to get there. We can use the Converge iterator to keep applying the Id!PrevId
dictionary to the IDs until the results stop changing:
update OriginalId:(Id!PrevId)/[Id] from table
This exploits implicit iteration. On each application of the dictionary all the IDs get mapped to their previous ones. So there is no need to iterate through each ID and then recurse to find its original.
2022.04.19 06:55 AM
Are you missing something on the left hand side of your = sign?
Also, could you provide a few example rows of the table you're working with? Thanks
2022.04.19 06:59 AM
Couple of syntax errors above, but let’s break down what we can. The trailing backtick was probably you trying to use Markdown for the expression; we can ignore that.
The query defines a new column OriginalId
by applying a lambda to each ID. The lambda is projected on (curried to) its second argument. That is, within the lambda y
refers to Id!PrevId
, which is a dictionary mapping IDs to previous IDs. The lambda has two expressions. The first expression applies y
(the dictionary) to x
(the ID) to get the previous ID, x1
. The second expression is a ternary conditional, Cond. This tests x1
and here is your second syntax error: the comparison term is missing. I strongly suspect it should be x
. That is, if x=x1
, if the previous ID is the same as this ID, then return it as the result. Otherwise apply .z.s
to x1
and y
. Now .z.s
is a reference to the current function, so this is a recursion; it ends when the ‘previous’ ID is just the ID.
There is a simpler way to get there. We can use the Converge iterator to keep applying the Id!PrevId
dictionary to the IDs until the results stop changing:
update OriginalId:(Id!PrevId)/[Id] from table
This exploits implicit iteration. On each application of the dictionary all the IDs get mapped to their previous ones. So there is no need to iterate through each ID and then recurse to find its original.
2022.04.20 07:31 PM
i am missing the ` before the x1, update originalId:{x1:y x;$[ `=x1;x;.z.s[x1;y]]} [; Id!PrevId] each Id from table` so basically if prev id is empty then stop iterating. How will that work i assume at each id it only has one map id!prev how will it iterate through to find the ultimate id?
2022.04.21 03:34 AM
The dictionary Id!PrevID
is a unary. Applying the Converge iterator to a unary f
derives a function f/
(f
Over). When you evaluate f/[x]
, the unary f
gets applied successively until either (a) the result stops changing (convergence) or (b) the result matches x
– i.e. comes full circle.
The white paper on iteration has some examples of iterating lists and dictionaries as finite-state machines.
All this assumes your ID => previous ID paths actually terminate! (You can use the Converge iterator to start an open loop!)
EMEA
Tel: +44 (0)28 3025 2242
AMERICAS
Tel: +1 (212) 447 6700
APAC
Tel: +61 (0)2 9236 5700
KX. All Rights Reserved.
KX and kdb+ are registered trademarks of KX Systems, Inc., a subsidiary of FD Technologies plc.