How to filter the values of msg.payload?

Hi there,

I'm somehow new to Node-RED and I like it very much as I've managed to do some mini personal projects with it.

Right now, I'm stuck with a payload that needs to get filtered out - it looks very similar to the following example as the real one contains hundreds or even thousands of items:

  • This is how the payload looks like in the debug window:
    Screenshot-1

  • This is the payload copy:

{"file_name":"value","filename":"value","name":"value","test":"value","name_file":"value"}

I wish to filter the results of the payload to get only the ones that are ending in 'name'.
I've been trying to search for an answer and the only one that was somehow useful was this one:
https://discourse.nodered.org/t/function-node-to-filter-2-values-out/13296/13?u=relic

More specifically, this line of code (the first one gives me 'undefined' in a change node):

payload ~> | $ | {}, $keys($)~>$filter(/.*_qc/) |

The problem with the above code is that I don't understand it in order to modify it to my liking (I don't know what these signs mean or what they are doing ~>, | $ |, ($) and the last | from the end).

If I edit it from /.*_qc/ to /name/ or to /.*name/or to /name.*/, it doesn't really do much - it filters the results, but now how I want to.

This is the payload:

{"file_name":"value","filename":"value","name":"value","test":"value","name_file":"value"}

This is the filtered payload (with the above code):

{"name":"value","test":"value","name_file":"value"}

This is what I'm trying to achieve:

{"file_name":"value","filename":"value"}

Hopefully I wrote everything in detail in order to get some help, examples or guidance to achieve this! :smile:

function node...

msg.payload = {
  filename: msg.payload.filename,
  file_name: msg.payload.file_name
}
return msg;

I have to ask why though? Typically, you just use the values you want in the next node and ignore the rest!

Try this JSONata expression

$sift(payload, function($v,$k){$contains($k,/\wname$/)}) 
2 Likes

It worked flawlessly!

Please, may I know how you managed to do it so quickly? I'm not used to write expressions, and if you could give me some guidance about how to create / apply them, that would be great!

Looking forward to your reply before I mark it as Solution.

I like that JSONata version. Well done :slight_smile:

But as for most, it takes to learn it to get such problems solved.
Meanwhile there is pretty many ways to do it with known tools...

function removeKey(k){
    if(k.startsWith('name') || !k.endsWith('name')){
        delete msg.payload[k] 
    }
}
Object.keys(msg.payload).forEach(k => removeKey(k))
return msg;
1 Like

Your method is great as well! Thank you very much!

Jsonata is not the most easy to learn and has it quirks.
With this problem we need to check the key, so i just used $sift() to iterate over the object. The check is if key contains name at end ( $ ) of string with 1 \w (word part) in front of it.

As @hotNipi shows there are many other ways, ie another js version.

for(let key in msg.payload){
    if (!(/\wname$/).test(key)){delete msg.payload[key]}
}
return msg;
2 Likes

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