Created
May 15, 2026 14:43
-
-
Save trycf/8de9a2fa00b68d8849dd99af45ea1050 to your computer and use it in GitHub Desktop.
TryCF Gist
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <cfscript> | |
| private struct function splitTargetPath(required string targetPath, required array splittedSourcePath) { | |
| local.splittedTargetPath = []; | |
| local.indexPath = "" | |
| local.startPos = 1; | |
| for (local.token in arguments.splittedSourcePath) { | |
| local.splitTokenLen = listLen(local.token.path, "."); | |
| local.splitTokenPath = arrayToList( | |
| arraySlice( | |
| listToArray(arguments.targetPath, "."), | |
| local.startPos, | |
| local.splitTokenLen | |
| ) | |
| ); | |
| arrayappend( | |
| local.splittedTargetPath, | |
| {path = local.splitTokenPath, counter = local.token.counter} | |
| ); | |
| local.indexPath = listAppend( | |
| local.indexPath, | |
| local.token.counter > 0 ? "#local.splitTokenPath#[#local.token.counter#]" : "local.splitTokenPath", | |
| "." | |
| ) | |
| local.startPos += local.splitTokenLen; | |
| } | |
| return { | |
| splittedPath = local.splittedTargetPath, | |
| indexPath = local.indexPath | |
| }; | |
| } | |
| private struct function splitSourcePath(string sourcePath) { | |
| // Leggo il path splittato | |
| local.splittedPath = []; | |
| local.noIndexPath = "" | |
| local.pathToken = {path = "", counter = 0}; | |
| for (local.token in listToArray(arguments.sourcePath, ".")) { | |
| // Ricerco l'indice al fondo che indica un array | |
| local.arraycounterPos = reFind("\[[0-9]+\]$", local.token); | |
| if (local.arraycounterPos > 0) { | |
| // Ho trovato un array | |
| // 1. chiudo il path token aggiungendo il token senza indice e lo aggiungo all'array principale | |
| // aggiorno il noIndexPath con il token senza indice | |
| // Reinizializzo la struct per il nuovo path token | |
| local.noIndexToken = left(local.token, local.arraycounterPos - 1) | |
| local.pathToken.path = listappend(local.pathToken.path, local.noIndexToken, "."); | |
| local.pathtoken.counter = val( | |
| mid( | |
| local.token, | |
| local.arraycounterPos + 1, | |
| len(local.token) - (local.arraycounterPos + 1) | |
| ) | |
| ); | |
| arrayAppend(local.splittedPath, local.pathToken); | |
| local.noIndexPath = listappend(local.noIndexPath, local.noIndexToken, "."); | |
| local.pathToken = {path = "", counter = 0}; | |
| } else { | |
| // Trovato una struct | |
| // Accodo al path token | |
| // Accodo al noIndexPath | |
| local.pathToken.path = listappend(local.pathToken.path, local.token, "."); | |
| local.noIndexPath = listappend(local.noIndexPath, local.token, "."); | |
| } | |
| } | |
| // Al fondo, se è rimasto un pathtoken con un percorso, aggiungo anche lui al path splittato | |
| if (local.pathToken.path != "") { | |
| arrayAppend(local.splittedPath, local.pathtoken); | |
| } | |
| return { | |
| splittedPath = local.splittedPath, | |
| noIndexPath = local.noIndexPath | |
| }; | |
| } | |
| private void function applyTransform(required struct target, required any source, required string sourcePath) { | |
| local.mappingrules = { | |
| "testa.ordine" = "header.order", | |
| "testa.data" = "header.date", | |
| "dettaglio.prodotto" = "detail.product", | |
| "dettaglio.riga" = "detail.row" | |
| } | |
| if (isStruct(arguments.source)) { | |
| // Se l'elemento passato è una source, si esgue loop sulle chiavi e si riapplica la trasformazione | |
| for (local.key in arguments.source) { | |
| applytransform( | |
| target = arguments.target, | |
| source = arguments.source[local.key], | |
| sourcePath = listappend(arguments.sourcePath, local.key, ".") | |
| ); | |
| } | |
| } else if (isArray(arguments.source)) { | |
| // Elemento array: eseguo un loop e aggiungo [n] al'elento nella dot notation | |
| for (local.idx = 1; local.idx <= arrayLen(arguments.source); local.idx++) { | |
| applytransform( | |
| target = arguments.target, | |
| source = arguments.source[local.idx], | |
| sourcePath = "#arguments.sourcePath#[#local.idx#]" | |
| ) | |
| } | |
| } else if (isSimpleValue(arguments.source)) { | |
| // Elemento foglia: ricerco se esiste un mapping - Se esiste creo l'elemento corrispondente | |
| // Splitto e normalizzo il path per le successive operazioni | |
| local.nomalizedPath = splitSourcePath(arguments.sourcePath); | |
| local.noIndexPath = local.nomalizedPath.noIndexPath; | |
| local.splittedPath = local.nomalizedPath.splittedPath; | |
| if (structKeyExists(local.mappingrules, local.noIndexPath)) { | |
| local.target_path = local.mappingrules[local.noIndexPath]; | |
| // Da qui in poi va risistemato... | |
| // 1. va riscritto il target path con la stessa spezzatura del source path | |
| // poi va gestito.... | |
| // estraggo la foglia del target path | |
| local.target_path_len = listLen(local.target_path, "."); | |
| local.target_path_leaf = listGetAt(local.target_path, local.target_path_len, "."); | |
| local.target_path_ancestors = listDeleteAt(local.target_path, local.target_path_len, "."); | |
| // Accedo al nodo che devo modificare e lo aggiorno | |
| local.target = structGet("arguments.target.#local.target_path_ancestors#"); | |
| local.target[local.target_path_leaf] = arguments.source; | |
| } | |
| } | |
| }; | |
| local.source = { | |
| "testa": {"ordine": "ABCD", "data": "2026-01-01"}, | |
| "dettaglio": [ | |
| {"riga": 1, "prodotto": "pippo"}, | |
| {"riga": 2, "prodotto": "cippo"}, | |
| {"riga": 3, "prodotto": "lippo"} | |
| ] | |
| }; | |
| local.target = {}; | |
| applyTransform(target = local.target, source = local.source, sourcePath = "") | |
| writedump(local.target); | |
| </cfscript> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment