Combine loop through 2dim-array and send to different outputs

#1

Hi,

I am stuck with a stupid problem in a function: I want to combine looping through the entries in a two-dimensional array with sending the value in [x][1] to the respective output number found in [x][0] (number of outputs is fixed to 10, number of entries in array varies).
I am aware of how to do a loop in a function and I also do know how to send info to a special output only, both described here: https://nodered.org/docs/writing-functions#multiple-messages, but I have no idea how to combine those. Either I break the loop, all is sent to the first output only or as usual I do have a bunch of error messages :slight_smile:

Most probably the solution is super simple, or one simply does not do it like this but completely different. Unfortunately I could not find any examples/solutions on this yet.
Thx for any help here

0 Likes

#2

You can either build the array of arrays using the various array methods available, or, possibly simpler in this case, you can use node.send to send the messages one at a time from within the loop. So for example if you want to send a message just to output 3 you can use
node.send(null, null, msg);
That will send nothing on outputs 1 and 2, will send msg to output 3 and will send nothing to any later outputs. If it makes the coding easier for your ten outputs you can include all the nulls after the msg too.
However you might make life simpler by first feeding it into a split node to split it into a sequence of messages containing a single dimension array. I am not entirely certain what you are doing though, so whether it will split it the right way I don't know.

0 Likes

#3

Hi Colin,
thx for your feedback! I will split the various actions I need to have accomplished accordingly and not try to have everything packed into one single function. You are right, one can make life simpler and functional, when doing things step by step. Had my brain completely locked in a dead end.
Thx again and nice greetings

0 Likes

#4

Sounds like you need to "pivot" your array of [port#, value]pairs into an array of array values, indexed by the port# -- using some actual data would be helpful here.

But as an example, here is one way to restructure your data...

// array of [port#,value] pairs
var arr = [[3, 'a'], [7, 'b'], [3, 'c'], [1, 'd']];
// create an empty array with length = # of output ports
var out = new Array(node.outputs).fill();
// replace each element with a filtered list of values
return out.map((d,i) => arr.filter(t => t[0] == i).map(v => ({payload: v[1]})));

The resulting output is an array of arrays (some of which may be empty), grouped by the port #:

[
  [],
  [ { payload: 'd' } ],
  [],
  [ { payload: 'a' }, { payload: 'c' } ],
  [],
  [],
  [],
  [ { payload: 'b' } ],
  [],
  []
]

A more traditional approach is to loop through the incoming data array, building up the output arrays, somthing like this:

var out = [];
for (var i = 0; i < msg.payload.length; i++) {
    var tmp = out[msg.payload[i][0] || [];
    var obj = {payload: msg.payload[i][1];
    tmp.push(obj);
    out[msg.payload[i][0]] = tmp;
}
return out;

... but I just like using the array map() and filter() functions ;*)

0 Likes