Recentemente mi è capitata una problematica di questo tipo in
Power Automate, dato un set di dati che rappresentano dei task da completare
[
{"code": "P3.2", "predecessor": "-", "status": "Approved"},
{"code": "P3.3", "predecessor": "P3.2", "status": "Approved"},
{"code": "P3.4", "predecessor": "P3.3", "status": "Approved"},
{"code": "P3.5", "predecessor": "P3.4", "status": "Created"},
{"code": "P3.6", "predecessor": "P3.2;P3.4", "status": "Created"},
{"code": "P3.7", "predecessor": "P3.5", "status": "Created"},
{"code": "P3.8", "predecessor": "P3.6;P3.7", "status": "Created"}
]
identificare i successivi.
In pratica, il desiderata era che, ogni volta che un task veniva completato, (stato
Approved), dovevano essere identificati i processi non ancora completati, (stato
Created), dipendenti da quelli completati (proprietà
predecessor).
Quindi in base ai dati di esempio precedenti il risultato doveva essere questo:
[
{"code": "P3.5", "predecessor": "P3.4", "status": "Created"},
{"code": "P3.6", "predecessor": "P3.2;P3.4", "status": "Created"},
]
Ovvero
P3.5, in quanto dipendeva solo dal completamento del
P3.4, mentre
P3.6 perché richiedeva il completamento sia del
P3.2 che
P3.4.
FlowRealizzazione
La realizzazione volevo che fosse il più possibile efficiente, quindi ho escluso a priori l'uso dei cicli come
Apply to each ed ho usato solo le funzioni di
Data operation.
I dati di ingresso, normalmente presi da una sorgente dati, li ho rappresentati con la variabile
InputArray[
{"code": "P3.2", "predecessor": "-", "status": "Approved"},
{"code": "P3.3", "predecessor": "P3.2", "status": "Approved"},
{"code": "P3.4", "predecessor": "P3.3", "status": "Approved"},
{"code": "P3.5", "predecessor": "P3.4", "status": "Created"},
{"code": "P3.6", "predecessor": "P3.2;P3.4", "status": "Created"},
{"code": "P3.7", "predecessor": "P3.5", "status": "Created"},
{"code": "P3.8", "predecessor": "P3.6;P3.7", "status": "Created"}
]
Il passo successivo è identificare i task già approvati
From: variables('InputArray')
@equals(item()['status'], 'Approved')
selezionare solo la proprietà
codeFrom: body('Filter_array:_Approved')
Map: v = item()['code']
e trasformarla in una stringa, sostituire alcuni valori e riconvertirla in array di stringhe con i soli codici dei task completati
Inputs: split(slice(join(body('Select:_Codes'), ''), 6, -2), '"}{"v":"')
che da come risultato
[
"P3.2",
"P3.3",
"P3.4"
]
Infine possiamo selezionare solo gli elementi successi, acora da completare (stato
Created), che dipendono da quelli completati
From: variables('InputArray')
Inputs: @and(equals(length(intersection(split(item()['predecessor'], ';'), outputs('Compose:_ArrayOfCodes'))), length(split(item()['predecessor'], ';'))),equals(item()['status'],'Created'))
Il tutto grazie alla funzione intersection(array1, array2) che ritorna solo gli elementi che coincidono, nei due array passati.
Poi confrontando la lunghezza dell'array risultante con l'array di partenza: length(split(item()['predecessor'], ';')).
Il risultato è questo
[
{
"code": "P3.5",
"predecessor": "P3.4",
"status": "Created"
},
{
"code": "P3.6",
"predecessor": "P3.2;P3.4",
"status": "Created"
}
]
L'unico
Apply to each sarà quello finale per ciclare sull'array risultate e aggiornare la sorgente dati.
intersection
La funzione
intersection(array1, array2, arrayN) restituice un array con i soli elementi presenti in tutti gli array passati.
Ad esempio questa espressione con 3 array di numeri
intersection(split('1|2|3|4','|'),split('4|1','|'),split('7|4|8|4|1','|'))
da come risultato