Sorting array values

what function or node can I use to sort the values in an array. I have the folowing output:
I have tried the sort node but I need to keep the id before the value
eg:
high_1:10 (high_1 needs to be kept so I can identify the value)

msg : Object

object

_msgid: "ac2284f8.25bb78"

payload: object

high_1: 10

high_3: 30

high_2: 20

high_4: 40

index: "high_4"

thanks.

What do you mean by sorting? You payload appears to be an object. An object's properties are not guaranteed to be in any particular order & cannot be meaningfully sorted.

Do you mean you want the objects sub-property with highest or lowest value?

You could (in a function node) convert the object to an array of arrays and sort them using Object.entries then sort the sub arrays it generates.

Hi Steve,
here is an example flow. indeed I need to sort the the array value from highest to lowest, but at the same time keep the id befor the value.

[{"id":"1f8dc3ff.c31f6c","type":"inject","z":"8623ccda.d27d5","name":"","props":[{"p":"payload"},{"p":"index","v":"high_1","vt":"str"},{"p":"id","v":"high_1","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"10","payloadType":"num","x":210,"y":200,"wires":[["8fcf9d30.d40bb"]]},{"id":"51f8d547.e717bc","type":"inject","z":"8623ccda.d27d5","name":"","props":[{"p":"payload"},{"p":"index","v":"high_2","vt":"str"},{"p":"id","v":"high_2","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"20","payloadType":"num","x":210,"y":240,"wires":[["8fcf9d30.d40bb"]]},{"id":"a82192a1.8eb22","type":"inject","z":"8623ccda.d27d5","name":"","props":[{"p":"payload"},{"p":"index","v":"high_3","vt":"str"},{"p":"id","v":"high_3","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"30","payloadType":"num","x":210,"y":280,"wires":[["8fcf9d30.d40bb"]]},{"id":"9ba0e0c5.5816e","type":"inject","z":"8623ccda.d27d5","name":"","props":[{"p":"payload"},{"p":"index","v":"high_4","vt":"str"},{"p":"id","v":"high_4","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"40","payloadType":"num","x":210,"y":320,"wires":[["8fcf9d30.d40bb"]]},{"id":"8fcf9d30.d40bb","type":"join","z":"8623ccda.d27d5","name":"phase_1","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"index","joiner":"\n","joinerType":"str","accumulate":false,"timeout":"","count":"4","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":520,"y":280,"wires":[["3552f9e5.fbbff6","5ee74743.313a08"]]},{"id":"19fdde66.c2f622","type":"debug","z":"8623ccda.d27d5","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":990,"y":320,"wires":},{"id":"3552f9e5.fbbff6","type":"sort","z":"8623ccda.d27d5","name":"","order":"ascending","as_num":false,"target":"","targetType":"seq","msgKey":"","msgKeyType":"elem","seqKey":"payload","seqKeyType":"msg","x":750,"y":320,"wires":[["19fdde66.c2f622"]]},{"id":"5ee74743.313a08","type":"debug","z":"8623ccda.d27d5","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":990,"y":280,"wires":}]

Much like your desire to keep order in your array, it is nice to keep order in the forum.

Please submit flows using the </> icon in the editor and place your flow in-between the resultant triple backslashes. You can go back and edit your last topic as such. Thank you.

1 Like

ok, sorry. I have changed the post.

Hi Steve,

I still cant get this to work. I have a test flow with 4 input values. If I activate them in random order, the array will sort them into the correct order but then I am missing the origin of the message. If you see the debug output the "high_1, 2, 3 anf 4" are current measuring devices, so I need to keep track of the current from highest to lowest. any tips?

thanks,

Duncan

[{"id":"808a10e4.3b93","type":"inject","z":"67fb2dd6.473094","name":"","props":[{"p":"payload"},{"p":"index","v":"high_1","vt":"str"},{"p":"id","v":"high_1","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"10","payloadType":"num","x":130,"y":80,"wires":[["b03d3f23.a06af","1fee61e5.52c81e"]]},{"id":"d855bc7e.718fe","type":"inject","z":"67fb2dd6.473094","name":"","props":[{"p":"payload"},{"p":"index","v":"high_2","vt":"str"},{"p":"id","v":"high_2","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"20","payloadType":"num","x":130,"y":120,"wires":[["b03d3f23.a06af","1fee61e5.52c81e"]]},{"id":"56867a1d.5d6f34","type":"inject","z":"67fb2dd6.473094","name":"","props":[{"p":"payload"},{"p":"index","v":"high_3","vt":"str"},{"p":"id","v":"high_3","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"30","payloadType":"num","x":130,"y":160,"wires":[["b03d3f23.a06af","1fee61e5.52c81e"]]},{"id":"771301f4.09eed","type":"inject","z":"67fb2dd6.473094","name":"","props":[{"p":"payload"},{"p":"index","v":"high_4","vt":"str"},{"p":"id","v":"high_4","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"40","payloadType":"num","x":130,"y":200,"wires":[["b03d3f23.a06af","1fee61e5.52c81e"]]},{"id":"b03d3f23.a06af","type":"join","z":"67fb2dd6.473094","name":"phase_1","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"index","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"4","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":480,"y":80,"wires":[["cc5cc1f3.4c447","8544d79a.65c728"]]},{"id":"85edb486.01e618","type":"debug","z":"67fb2dd6.473094","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":930,"y":80,"wires":[]},{"id":"cc5cc1f3.4c447","type":"sort","z":"67fb2dd6.473094","name":"","order":"ascending","as_num":false,"target":"","targetType":"seq","msgKey":"","msgKeyType":"elem","seqKey":"payload","seqKeyType":"msg","x":690,"y":80,"wires":[["85edb486.01e618"]]},{"id":"8544d79a.65c728","type":"debug","z":"67fb2dd6.473094","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":930,"y":40,"wires":[]},{"id":"59450a24.711bd4","type":"sort","z":"67fb2dd6.473094","name":"","order":"ascending","as_num":false,"target":"payload","targetType":"msg","msgKey":"","msgKeyType":"elem","seqKey":"payload","seqKeyType":"msg","x":720,"y":240,"wires":[["3f4bd05e.387c"]]},{"id":"3f4bd05e.387c","type":"debug","z":"67fb2dd6.473094","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":930,"y":240,"wires":[]},{"id":"1fee61e5.52c81e","type":"join","z":"67fb2dd6.473094","name":"phase_1","mode":"custom","build":"array","property":"payload","propertyType":"msg","key":"index","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"4","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":480,"y":240,"wires":[["59450a24.711bd4"]]}]
18-7-2021 22:23:34node: 8544d79a.65c728
msg : Object
object
_msgid: "6e87386a.26be88"
payload: object
high_2: 20
high_1: 10
high_3: 30
high_4: 40
index: "high_4"
id: "high_4"
18-7-2021 22:23:34node: 3f4bd05e.387c
msg : Object
object
_msgid: "6e87386a.26be88"
payload: array[4]
0: 10
1: 20
2: 30
3: 40
index: "high_4"
id: "high_4"

Anyone else with some advice for sorting object/key array from highest to lowest. I can get this to work.

[{"id":"fc3041ec.c63f3","type":"inject","z":"a07ca15d.8c543","name":"","props":[{"p":"payload"},{"p":"index","v":"high_1","vt":"str"},{"p":"id","v":"high_1","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"10","payloadType":"num","x":190,"y":340,"wires":[["6928ac67.618e64"]]},{"id":"eb1f8b0.c8f7f78","type":"inject","z":"a07ca15d.8c543","name":"","props":[{"p":"payload"},{"p":"index","v":"high_2","vt":"str"},{"p":"id","v":"high_2","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"20","payloadType":"num","x":190,"y":380,"wires":[["6928ac67.618e64"]]},{"id":"d17c5c48.29bc2","type":"inject","z":"a07ca15d.8c543","name":"","props":[{"p":"payload"},{"p":"index","v":"high_3","vt":"str"},{"p":"id","v":"high_3","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"30","payloadType":"num","x":190,"y":420,"wires":[["6928ac67.618e64"]]},{"id":"8b3186aa.6d6998","type":"inject","z":"a07ca15d.8c543","name":"","props":[{"p":"payload"},{"p":"index","v":"high_4","vt":"str"},{"p":"id","v":"high_4","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"40","payloadType":"num","x":190,"y":460,"wires":[["6928ac67.618e64"]]},{"id":"6928ac67.618e64","type":"join","z":"a07ca15d.8c543","name":"phase_1","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"index","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"4","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":420,"y":380,"wires":[["b31e51db.2cd6e","268cc495.900b2c"]]},{"id":"b31e51db.2cd6e","type":"debug","z":"a07ca15d.8c543","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":710,"y":340,"wires":[]},{"id":"268cc495.900b2c","type":"change","z":"a07ca15d.8c543","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$sort(payload, function($l, $r) {\t  $l.index.* > $r.index.*\t})","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":740,"y":380,"wires":[["e3c3fbbb.6929a8"]]},{"id":"e3c3fbbb.6929a8","type":"debug","z":"a07ca15d.8c543","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":990,"y":380,"wires":[]}]

You give no clues to whats this is for, so unsure if you need the object, or an array.

[{"id":"1f8dc3ff.c31f6c","type":"inject","z":"c74669a0.6a34f8","name":"","props":[{"p":"payload"},{"p":"index","v":"high_1","vt":"str"},{"p":"id","v":"high_1","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"10","payloadType":"num","x":110,"y":2580,"wires":[["8fcf9d30.d40bb"]]},{"id":"8fcf9d30.d40bb","type":"join","z":"c74669a0.6a34f8","name":"phase_1","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"index","joiner":"","joinerType":"str","accumulate":false,"timeout":"","count":"4","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":290,"y":2660,"wires":[["5ee74743.313a08","1cb732fc.93f6cd","3846fbf2.ce60f4"]]},{"id":"51f8d547.e717bc","type":"inject","z":"c74669a0.6a34f8","name":"","props":[{"p":"payload"},{"p":"index","v":"high_2","vt":"str"},{"p":"id","v":"high_2","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"20","payloadType":"num","x":130,"y":2620,"wires":[["8fcf9d30.d40bb"]]},{"id":"a82192a1.8eb22","type":"inject","z":"c74669a0.6a34f8","name":"","props":[{"p":"payload"},{"p":"index","v":"high_3","vt":"str"},{"p":"id","v":"high_3","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"30","payloadType":"num","x":130,"y":2660,"wires":[["8fcf9d30.d40bb"]]},{"id":"9ba0e0c5.5816e","type":"inject","z":"c74669a0.6a34f8","name":"","props":[{"p":"payload"},{"p":"index","v":"high_4","vt":"str"},{"p":"id","v":"high_4","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"40","payloadType":"num","x":130,"y":2700,"wires":[["8fcf9d30.d40bb"]]},{"id":"5ee74743.313a08","type":"debug","z":"c74669a0.6a34f8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":490,"y":2660,"wires":[]},{"id":"1cb732fc.93f6cd","type":"change","z":"c74669a0.6a34f8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$each($$.payload, function($v,$k){\t{$k:$v}\t})^(>*)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":430,"y":2720,"wires":[["19fdde66.c2f622"]]},{"id":"3846fbf2.ce60f4","type":"change","z":"c74669a0.6a34f8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$merge($each($$.payload, function($v,$k){\t{$k:$v}\t})^(>*))","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":420,"y":2780,"wires":[["f188d24.4ddcbb"]]},{"id":"19fdde66.c2f622","type":"debug","z":"c74669a0.6a34f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":590,"y":2700,"wires":[]},{"id":"f188d24.4ddcbb","type":"debug","z":"c74669a0.6a34f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":590,"y":2780,"wires":[]}]

[edit] Jsonata expression to create a sorted array

$each($$.payload, function($v,$k){	{$k:$v}	})^(>*)

Jsonata expression to create a sorted object

$merge($each($$.payload, function($v,$k){	{$k:$v}	})^(>*))

Hi,

I have 4 inject nodes "high_1, 2, 3 and 4" each with thier own value. I want the output payload to be organised so that they are in order from the high to lowest but keep thier key values. eg

18-7-2021 22:23:34node: 8544d79a.65c728
msg : Object
object
_msgid: "6e87386a.26be88"
payload: object
high_2: 20
high_1: 10
high_3: 30
high_4: 40
index: "high_4"
id: "high_4"

but then in the order 40, 30, 20, 10

thanks

As I said before,

Ps, when you copy a Payload value from the debug output, use the copy value button that appears under your mouse cursor when you hover over the property in the debug window. Then paste it into a code block

```
like this
```

That way we can simply copy and paste it and develop a solution for you, otherwise we have to recreate your payload.

Hi Steve, now I am really lost. surely there must be an easier way in node-red. Essentially all I want to do is sort the values from 4 power sources (kw) from highest to lowest, but at the same time still keep track of which power group is the highest so I can turn it off for load shedding. I hope this makes sense.
Duncan

copy your output (before sorting) using the copy value button...

image

... then paste it into the reply ...

ebHFVzbEOV

... that way, we can simply copy you the value you paste (in the correct format) ready to develop a solution for you.

ok this is the result:

[{"high_4":40,"high_3":30,"high_2":20,"high_1":10}]

and this is the flow:

[{"id":"525fba1d.f9b784","type":"inject","z":"f1bb9a74.8ac3b8","name":"","props":[{"p":"payload"},{"p":"index","v":"high_1","vt":"str"},{"p":"id","v":"high_1","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"10","payloadType":"num","x":250,"y":140,"wires":[["7641fb96.218e64"]]},{"id":"31dd5125.4063fe","type":"inject","z":"f1bb9a74.8ac3b8","name":"","props":[{"p":"payload"},{"p":"index","v":"high_2","vt":"str"},{"p":"id","v":"high_2","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"20","payloadType":"num","x":250,"y":180,"wires":[["7641fb96.218e64"]]},{"id":"97da6d6.f57a99","type":"inject","z":"f1bb9a74.8ac3b8","name":"","props":[{"p":"payload"},{"p":"index","v":"high_3","vt":"str"},{"p":"id","v":"high_3","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"30","payloadType":"num","x":250,"y":220,"wires":[["7641fb96.218e64"]]},{"id":"b5f7eb1a.f80988","type":"inject","z":"f1bb9a74.8ac3b8","name":"","props":[{"p":"payload"},{"p":"index","v":"high_4","vt":"str"},{"p":"id","v":"high_4","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"40","payloadType":"num","x":250,"y":260,"wires":[["7641fb96.218e64"]]},{"id":"7641fb96.218e64","type":"join","z":"f1bb9a74.8ac3b8","name":"phase_1","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"index","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"4","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":480,"y":180,"wires":[["e960c5f1.90b4a8"]]},{"id":"e960c5f1.90b4a8","type":"change","z":"f1bb9a74.8ac3b8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$sort(payload, function($l, $r) {\t  $l.index.* > $r.index.*\t})","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":820,"y":180,"wires":[["fa5a7cb3.51472"]]},{"id":"fa5a7cb3.51472","type":"debug","z":"f1bb9a74.8ac3b8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1050,"y":180,"wires":[]}]

And what is it you expect as the output from that?

Hi @Duncan

The key thing here is you do not have an array to sort. At the moment you have an object with properties.

I see @E1cid has provided an example, but I'm not in a position to import his flow and with no description included I'm not sure what approach he has taken. So this may be a duplicate of that.

The first step is to convert your object to an array that can be sorted.

Given msg.payload is an object of the form:

{
  high_2: 20,
  high_1: 10,
  high_3: 30,
  high_4: 40
}

Then one way to covert it to an array is:

let myArray = Object.entries(msg.payload).map((k,v) => { return { key: k, value: v}})

That gives you an array of objects like:

[
   { key: "high_2", value: 20 }
   ...
]

You can then sort it with:

myArray.sort((A,B) => A.value - B.value)

(You may need to swap the order of A.value/B.value depending on the order you want)

1 Like

Hi Nick, I am really greatfull for your reply. Unfortunately when I use this code in a function node (presume) I get nothing on the output. I have been tinkering with node-red for a while now, but never need to go onto the coding.

let myArray = Object.entries(msg.payload).map((k,v) => { return { key: k, value: v}})

To all and @E1cid,

E1cid did indeed post a solution, Im sorry to have missed it thanks for the help and tips.

this will work for me.
Duncan

Hi .. most probably you havent assigned the result of myArray to msg.payload or returned the msg from the function node.

let myArray = Object.entries(msg.payload).map(([k, v]) => { return { key: k, value: v } })
myArray.sort((A, B) => B.value - A.value)

msg.payload = myArray;

return msg;

I have been using this in my application for the past few weeks, thanks.
Could you advise me how to display the number count of the sorting. Lets say the array has 4 parts, I need to display the count from 1 to 4.
thanks!

you mean to add like an index before the sorting of the array ?

[{"id":"66216b8c6396e40d","type":"inject","z":"4895ea10b4ee9ead","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"high_2\":20,\"high_1\":10,\"high_3\":30,\"high_4\":40}","payloadType":"json","x":270,"y":960,"wires":[["2e3f861778cf642e"]]},{"id":"9387422d37e76b7c","type":"debug","z":"4895ea10b4ee9ead","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":590,"y":960,"wires":[]},{"id":"2e3f861778cf642e","type":"function","z":"4895ea10b4ee9ead","name":"","func":"let myArray = Object.entries(msg.payload).map(([k, v], index) => {\n    return {\n        index: index + 1,\n        key: k,\n        value: v\n    }\n})\n\nmyArray.sort((A, B) => B.value - A.value)\n\nmsg.payload = myArray;\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":960,"wires":[["9387422d37e76b7c"]]}]