Anche se ho lavorato a JMP da più di 10 anni sto ancora imparando cose nuove. Più di recente, è stata una nuova visione del diagramma di Ishikawa e del potere della ricorsione. Sebbene entrambi siano in circolazione da secoli, è stato solo quando ho avuto una sfida specifica che mi sono preoccupato di loro. Questa nuova motivazione è arrivata durante lo sviluppo Geocodifica 2020 , un componente aggiuntivo che utilizza un'API REST per comunicare con un server. I dati, provenienti dal server, erano sotto forma di un array JSON che poteva essere abbastanza grande, a seconda dei dati. Una delle gemme nascoste in JMP (o più specificamente, in JSL), è il comando Parse JSON (), che traduce un array JSON in un elenco JSL o in un array associativo. È stato un buon punto di partenza, ma comunque, se volevo acquisire parti specifiche dei dati, avevo bisogno di sapere come trovarle e affrontarle. Non è un compito facile se quell'array è composto da diverse centinaia di elementi, profondamente impilati in elenchi e array. Quindi, ho deciso di scrivere questo utile programmino, stackmole.jsl , per darmi una panoramica della struttura dei dati. E non ero un JMPer rispettabile se non cercavo una presentazione grafica.
Ogni chiamata al server potrebbe fornire dati con profondità, larghezza e volume completamente diversi. La presenza o l'assenza di una parte dei dati dipende dai dati stessi. È impossibile sapere in anticipo che aspetto abbia quella struttura dati. Avevo bisogno di un programma che potesse decidere da solo se continuare a cercare dati, se cercare l'elenco o l'array successivo o se fosse alla fine. La ricorsione è stata la mia risposta a questo problema. Conosco definizioni ricorsive in matematica, ma come funzionerebbero in una struttura dati? Sorprendentemente bene!
Strutture dati e ricorsione passo dopo passo
Ricorsione significa che applico la stessa regola o logica al risultato che ho prodotto nel passaggio precedente. La definizione di fattoriale di un numero intero è l'esempio più noto. Il fattoriale di un numero è il prodotto di quel numero con tutti i numeri più piccoli fino a 1, il che significa che il fattoriale di 3 è spesso scritto come 3! = 3 * 2 * 1 = 6. La Guida allo scripting mostra le istruzioni per quella routine:
myfactorial = Function( {a},
If( a == 1,
1,<BR /> a * Recurse( a - 1 )
)
);
La ricorsione può essere applicata solo a una funzione; il comando si trova nella funzione stessa e chiama quella funzione con il nuovo argomento. Nell'esempio di 3!, La funzione viene chiamata con 3 come argomento: myfactorial (3). Poiché 3 non è uguale a 1, viene eseguita la clausola else dell'istruzione IF. Ciò significa moltiplicare 3 per il risultato di myfactorial (2). Di nuovo, questo non è uguale a 1 e la clausola else ora moltiplica 2 per il risultato di myfactorial (1). Ora c'è un risultato; è 1.
JMP ricorda che l'attività aperta prima era moltiplicare 2 con questo risultato (2 * 1 = 1) e l'attività prima era moltiplicare 3 con il risultato della ricorsione, che è 3 * 2 = 6. Poiché 3 era al livello più alto, il risultato è 6. Il meccanismo può essere immaginato mentre scendeva una scala. Ad ogni passaggio, l'attività aperta viene rimossa. Il programma esegue tutti i passaggi necessari fino a quando non c'è più ricorsione. Sulla via del ritorno su per le scale, raccoglie tutti i compiti e finisce al piano di partenza con il risultato.
JSL conosce alcune raccolte di dati, (ad esempio, variabili che rappresentano molti valori). Le strutture che possono essere analizzate da questo programma sono elenchi e array associativi. Gli elenchi sono elenchi separati da virgole di elementi come:
list = {"a", "b", 1, 2}
Gli array associativi sono elenchi di coppie chiave-valore.
assarr = ["a" => "Questo", "b" => "è", "c" => "a", "d" => "frase"];
Il primo elemento di ogni coppia è la chiave; il secondo è il valore. Le chiavi devono essere univoche e sono ordinate internamente in ordine alfabetico.
A causa dei diversi concetti, ogni struttura necessita di diversi comandi per modificare o leggere il proprio contenuto, che possono essere consultati nella Guida allo scripting. Quale output produrrebbe la talpa dello stack dall'analisi di un semplice elenco?
list = {"a1", "b1", "c1"};
stackmole (l);

La tabella dei dati è l'elenco degli elementi trovati dalla talpa durante il drill-down nella profondità della struttura. Le righe devono essere interpretate da una prospettiva infantile. L'intero set è una lista, con il primo figlio (al livello 2) come primo elemento in quella lista. Questo figlio (riga 2) è il dato e il suo valore è "a1". I dati sono l'endpoint di ogni viaggio, il che significa che se non ci sono altri elementi, l'elemento è zero.
Più informativo è il diagramma causa ed effetto, che è il diagramma di Ishikawa nel suo stile gerarchico. In basso, ci sono i valori dei dati sopra di loro i loro indici tra parentesi quadre. In questo piccolo esempio, il nome dell'intero set è "list", quindi, se vuoi ottenere "b1", è list [2].
Il grafico parallelo mostra che l'intero set si divide in tre elementi e gli elementi del livello successivo non si dividono più, poiché contengono i dati. Anche se aiuta a capire le piccole strutture, alla fine di questo articolo, mostrerò un diagramma parallelo colorato che non aiuta nulla.
I risultati per un array associativo differiscono leggermente dal report elenco in quanto contengono i nomi delle chiavi:
sentencearray = ["a" => "This", "b" => "is", "c" => "a", "d" => "sentence"];
stackmole(sentencearray);

Il tipo dell'intero insieme è aa, che è l'abbreviazione di array associativo. L'intero set è chiamato "sentencearray"; se vuoi accedere alla parola "frase" in quell'array, fallo con sentencearray ["d"].
Questo metodo è semplice poiché utilizza una sola struttura con un insieme di elementi. Ma JMP consente di impilare queste strutture in modo e profondità arbitrari. Quindi, potresti avere elenchi di array associativi di array associativi di elenchi, ... In questo esempio:
array = ["2list1" => {{"4list1_1", "4list1_2", "4list1_3"}, {"4list2_1", "4list2_2"} },
"2list2" => {{"4list3_1", "4list3_2"}, "4element1" } ];
"Array" è un array associativo con due chiavi denominate "2list1" e "2list2". I valori di ciascuna chiave sono elenchi, il primo elenco sempre costituito da due elenchi, il secondo elenco costituito da un elenco e un elemento di dati. I numeri all'inizio di ogni termine indicano la profondità della pila in cui risiedono quegli elementi. Nell'analogia della scala, è il numero di gradini che devi scendere per raggiungere questo elemento.
In questo caso, la talpa dello stack fornisce le seguenti informazioni:

L'immagine mostra solo una parte della tabella dati che ora ha 21 righe. Il diagramma gerarchico è completo. Se vuoi arrivare all'elemento dati 4list3_2 (in grassetto), il percorso è:
matrice ["2list2"] [1] [2]
Di seguito è riportato un esempio di una trama parallela che non aiuta affatto, ma fornisce comunque uno schema interessante:

Il programma ha molti commenti che spiegano i singoli passaggi dell'analisi e come viene applicata la ricorsione.