JSONata сортировка / упорядочение по массиву - PullRequest
0 голосов
/ 24 декабря 2018

Я хочу заказать массив.Выражение JSONata ниже имеет входящий массив следующим образом.

[{"id":"Air-1a",
  "Controller":"ESP62",
 "Cntr-TaskNo":10,
 "Cntr-GPIO":13,
 "name":"Air",
 "valueName":"Humidity",
 "Sensor":"DHT22",
 (and many other key pairs)}, 
 {next object}, ...]

Затем я преобразую массив следующим выражением JSONata:

payload.(
        { "Controller" : $.Controller,
          "Cntr-TaskNo": $.CntrDef.TaskNo,
          "Cntr-GPIO"  : $.CntrDef.GPIO,
          "name"       : $.name,
          "valueName"  : $.valueName,
          "Sensor"     : $.Sensor,
          "id"         : $.id
        }
) 

Но теперь я хочу - в том же JSONataвыражение, сортировка сначала на контроллере, а затем на GPIO.Чтобы попробовать сначала только с контроллером.

Я пытался:

payload.(
        { $sort("Controller",function($l, $r){$l.Controller > $r.Controller}) : $.Controller ,
          "Cntr-TaskNo": $.CntrDef.TaskNo,
          "Cntr-GPIO"  : $.CntrDef.GPIO,
          "name"       : $.name,
          "valueName"  : $.valueName,
          "Sensor"     : $.Sensor,
          "id"         : $.id
        }
) 

А также пытался добавить функцию сортировки в конце с помощью команды ~> chaining.Я также попробовал оператор order-by .

Может ли кто-нибудь указать мне правильное направление?

// ---------- Новый поток с измененным 'ESP62' на '-', который не работает:

[{"id":"874b0c77.f87418","type":"inject","z":"6f27a311.d135bc","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":200,"y":180,"wires":[["8c196590.c20638"]]},{"id":"8c196590.c20638","type":"change","z":"6f27a311.d135bc","name":"Dataset","rules":[{"t":"set","p":"payload","pt":"msg","to":"[{\"id\":\"Air-1a\",\"Controller\":\"ESP62\",\"CntrTaskNo\":10,\"CntrGPIO\":13,\"name\":\"Air\",\"valueName\":\"Humidity\",\"Sensor\":\"DHT22\",\"aaa\":\"111\",\"bbb\":\"222\",\"ccc\":\"333\"},{\"id\":\"Air-2a\",\"Controller\":\"ESP72\",\"CntrTaskNo\":11,\"CntrGPIO\":14,\"name\":\"Air\",\"valueName\":\"Humidity\",\"Sensor\":\"DHT22\",\"aaa\":\"444\",\"bbb\":\"555\",\"ccc\":\"666\"},{\"id\":\"Air-1a\",\"Controller\":\"ESP62\",\"CntrTaskNo\":2,\"CntrGPIO\":9,\"name\":\"Air\",\"valueName\":\"Humidity\",\"Sensor\":\"DHT22\",\"aaa\":\"777\",\"bbb\":\"888\",\"ccc\":\"999\"},{\"id\":\"Air-1a\",\"Controller\":\"-\",\"CntrTaskNo\":10,\"CntrGPIO\":12,\"name\":\"Air\",\"valueName\":\"Humidity\",\"Sensor\":\"DHT22\",\"aaa\":\"777\",\"bbb\":\"888\",\"ccc\":\"999\"}]","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":180,"wires":[["13981162.14e28f"]]},{"id":"c8a256a5.a170c8","type":"debug","z":"6f27a311.d135bc","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":690,"y":180,"wires":[]},{"id":"13981162.14e28f","type":"change","z":"6f27a311.d135bc","name":"Jsonata $sort","rules":[{"t":"set","p":"payload","pt":"msg","to":"($sort(payload,function($l , $r){$l.Controller > $r.Controller}) ; \t$sort(payload,function($l , $r){$l.CntrGPIO > $r.CntrGPIO}))","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":180,"wires":[["c8a256a5.a170c8"]]}]

Ответы [ 2 ]

0 голосов
/ 02 января 2019

Вы можете отсортировать массив, используя следующее выражение:

payload^(Controller, CntrDef.GPIO)

Оператор упорядочения ^ отсортирует массив, сначала увеличив значение Controller, затем увеличив значение CntrGPIO.Затем вы можете преобразовать каждый объект в этом массиве

payload^(Controller, CntrDef.GPIO).{
   "Controller" : Controller,
   "Cntr-TaskNo": CntrDef.TaskNo,
   "Cntr-GPIO"  : CntrDef.GPIO,
   "name"       : name,
   "valueName"  : valueName,
   "Sensor"     : Sensor,
   "id"         : id
}
0 голосов
/ 25 декабря 2018

Я предлагаю сначала отсортировать набор данных, а затем преобразовать уже отсортированный массив объектов.Преобразование тривиально, и вы хотите знать, как сортировать, поэтому ниже я покажу одно из возможных решений.Он использует выражение с двумя объединенными функциями $ sort.

Отредактировано после лучшего понимания требования.

Я успешно протестировал поток Node-RED, используя это выражение в узле изменений:

($a := $sort(payload,function($l , $r){$l.Controller > $r.Controller}) ; $sort($a,function($l , $r){(($l.Controller = $r.Controller) and ($l.CntrGPIO > $r.CntrGPIO))}))

Поток (содержит набор данных, жестко закодированный):

[{"id":"a7814b7e.3adeb8","type":"tab","label":"Flow 4","disabled":false,"info":""},{"id":"8bf10833.c71748","type":"inject","z":"a7814b7e.3adeb8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":140,"wires":[["9e365564.edca08"]]},{"id":"9e365564.edca08","type":"change","z":"a7814b7e.3adeb8","name":"Dataset","rules":[{"t":"set","p":"payload","pt":"msg","to":"[{\"id\":\"Air-1a\",\"Controller\":\"ESP62\",\"CntrTaskNo\":10,\"CntrGPIO\":13,\"name\":\"Air\",\"valueName\":\"Humidity\",\"Sensor\":\"DHT22\",\"aaa\":\"111\",\"bbb\":\"222\",\"ccc\":\"333\"},{\"id\":\"Air-2a\",\"Controller\":\"ESP72\",\"CntrTaskNo\":11,\"CntrGPIO\":14,\"name\":\"Air\",\"valueName\":\"Humidity\",\"Sensor\":\"DHT22\",\"aaa\":\"444\",\"bbb\":\"555\",\"ccc\":\"666\"},{\"id\":\"Air-1a\",\"Controller\":\"ESP62\",\"CntrTaskNo\":2,\"CntrGPIO\":9,\"name\":\"Air\",\"valueName\":\"Humidity\",\"Sensor\":\"DHT22\",\"aaa\":\"777\",\"bbb\":\"888\",\"ccc\":\"999\"},{\"id\":\"Air-1a\",\"Controller\":\"-\",\"CntrTaskNo\":10,\"CntrGPIO\":12,\"name\":\"Air\",\"valueName\":\"Humidity\",\"Sensor\":\"DHT22\",\"aaa\":\"777\",\"bbb\":\"888\",\"ccc\":\"999\"}]","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":300,"y":140,"wires":[["762f6421.074fec"]]},{"id":"f827bddb.c9acd","type":"debug","z":"a7814b7e.3adeb8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":630,"y":140,"wires":[]},{"id":"762f6421.074fec","type":"change","z":"a7814b7e.3adeb8","name":"Jsonata $sort","rules":[{"t":"set","p":"payload","pt":"msg","to":"($a := $sort(payload,function($l , $r){$l.Controller > $r.Controller}) ; $sort($a,function($l , $r){(($l.Controller = $r.Controller) and ($l.CntrGPIO > $r.CntrGPIO))}))","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":140,"wires":[["f827bddb.c9acd"]]}]

также протестирован в тренажере Jsonata: http://try.jsonata.org/S1IlT3y-E

...