Split of string using JSONata in a change node?

OK, so I like many of us that us NR, see JSONata as this mystical experience that works at times well other times just not quite right way to do something. I just going to write a small function node to extract a string from a MQTT subscription string... and thought, hey, can I do this in a change node expression? Maybe even with JSONata?

Where msg.topic is 'command/target/status', and I want to pull 'target' from the topic? In a function node, easy, like msg.target = msg.topic.split(/)[1]. But a function node for a one-liner? How could you implement this in a change node? Of course the following does not work...

image

But hey, someone that know change nodes, expressions, or JSONata better than me, know a trick? Or am I just too far outside the box on this on?

msg.topic.split(/)[1]

is not what you specified in the expression.
but split is a function within jsonata, every function starts with $:

topic.$split("/")[1]

(omit msg)

That would be

$split($$.topic, "/")[1]

//or

($$.topic ~> $split("/"))[1]

OK, I get that the functions are referenced by $, but the $$ is giving me a head scratching. It reminds me a bit of a powershell or bash reference, like $? (bash) or $_ (powershell). How would one know or learn of such as $$ use and syntax? Clearly $.topic is a type of substitution? Shorthand reference?

it's just my convention, you can omit them if you wish. It comes into play with more complicated expressions. It reminds me what scope the property is in.
$$ is the msg/base scope, while $ is the curent scope.

Yeah, now I get it... like bash $? or powershell $_ is the 'current' context scope.

Well, "it works", but it is inherently slow, would not recommend it on large objects.

Just traverse down the path and start from there.
and this works perfectly fine topic.$split("/")[1]

Well when i tested there was no difference, running 1000 operations the average for both was 160ms. Again I do it as a matter of consistency and with more complicated expressions it makes sure i do not call a property from the wrong scope, since doing so I find less expressions fail. It works for me and cost me nothing.

topic.$split("/")[1] tells JSONata to map over topic as if an array and split each element and output index 1.
$split($$.topic, "/")[1] tells JSOnata to split topic and output index 1.
Both work just fine, as JSONata treats single string as a 1 element array.

It is no secret that JSONata can be 100's of times slower than native javascript.

Ofcourse, this does not become a dealbreaker with small(er) objects like this example, but if the path is known I would choose to traverse from there.

It is normally not 100's of times slower, bit of an exaggeration to say that. It is slower 1 to 4 ti.es normally, unless you have written a bad expression

So, the bottom line is... abusing a function node, if you get my meaning? Is really leaner and meaner, even though it does hide some of the elegance of a visual language. Just an observation.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.