Credo di aver appreso alcuni / molti / molti dei concetti di base alla base della programmazione funzionale in JavaScript. Tuttavia, ho difficoltà a leggere in modo specifico il codice funzionale, anche il codice che ho scritto, e mi chiedo se qualcuno può darmi suggerimenti, suggerimenti, migliori pratiche, terminologia, ecc. Che possono aiutare.
Prendi il codice qui sotto. Ho scritto questo codice Ha lo scopo di assegnare una percentuale di somiglianza tra due oggetti, tra dire {a:1, b:2, c:3, d:3}
e {a:1, b:1, e:2, f:2, g:3, h:5}
. Ho prodotto il codice in risposta a questa domanda su StackTranslate.it . Poiché non ero sicuro del tipo di somiglianza percentuale richiesta dal poster, ho fornito quattro diversi tipi:
- la percentuale di chiavi nel 1o oggetto che si trova nel 2o,
- la percentuale dei valori nel 1 ° oggetto che è possibile trovare nel 2 °, inclusi i duplicati,
- la percentuale dei valori nel 1 ° oggetto che è possibile trovare nel 2 °, senza duplicati consentiti, e
- la percentuale di {chiave: valore} si accoppia nel primo oggetto che si trova nel secondo oggetto.
Ho iniziato con un codice ragionevolmente imperativo, ma ho subito capito che si trattava di un problema adatto alla programmazione funzionale. In particolare, mi sono reso conto che se avessi potuto estrarre una o tre funzioni per ognuna delle quattro strategie di cui sopra che definivano il tipo di funzione che stavo cercando di confrontare (ad esempio le chiavi, i valori, ecc.), Allora potrei essere in grado di ridurre (perdona il gioco di parole) il resto del codice in unità ripetibili. Sai, mantenerlo ASCIUTTO. Quindi sono passato alla programmazione funzionale. Sono abbastanza orgoglioso del risultato, penso che sia ragionevolmente elegante e penso di aver capito cosa ho fatto abbastanza bene.
Tuttavia, anche dopo aver scritto il codice da solo e averne compreso ogni parte durante la costruzione, quando ora guardo indietro su di esso, continuo a essere più che un po 'confuso sia su come leggere una particolare mezza linea, sia su come "grok" ciò che sta facendo una particolare riga di codice. Mi ritrovo a creare frecce mentali per collegare diverse parti che si degradano rapidamente in un pasticcio di spaghetti.
Quindi, qualcuno può dirmi come "leggere" alcuni dei pezzi di codice più contorti in un modo che sia allo stesso tempo conciso e che contribuisce alla mia comprensione di ciò che sto leggendo? Immagino che le parti che mi ottengono di più siano quelle che hanno più frecce grosse in una riga e / o parti che hanno più parentesi in una riga. Anche in questo caso, alla fine, riesco a capire la logica, ma (spero) c'è un modo migliore per andare avanti rapidamente e chiaramente "prendendo" una linea di programmazione JavaScript funzionale.
Sentiti libero di usare qualsiasi riga di codice dal basso o anche altri esempi. Tuttavia, se vuoi alcuni suggerimenti iniziali da me, eccone alcuni. Inizia con una ragionevolmente semplice. Da vicino la fine del codice, c'è questa che viene passato come parametro a una funzione: obj => key => obj[key]
. Come si fa a leggerlo e capirlo? Un esempio è più una funzione completa dal prossimità della partenza: const getXs = (obj, getX) => Object.keys(obj).map(key => getX(obj)(key));
. L'ultima map
parte mi prende in particolare.
Si prega di notare, a questo punto nel tempo che sto , non alla ricerca di riferimenti a Haskell o simbolico notazione astratta o fondamenti della accattivarsi, ecc Quello che sto cercando è frasi in inglese che posso silenziosamente bocca mentre guardando una riga di codice. Se hai riferimenti che si rivolgono esattamente a questo, fantastico, ma non cerco anche risposte che dicano che dovrei andare a leggere alcuni libri di testo di base. L'ho fatto e ottengo (almeno una quantità significativa di) la logica. Inoltre, non ho bisogno di risposte esaustive (anche se tali tentativi sarebbero i benvenuti): anche le risposte brevi che forniscono un modo elegante di leggere una singola riga particolare di codice altrimenti problematico sarebbero apprezzate.
Suppongo che una parte di questa domanda sia: posso persino leggere il codice funzionale in modo lineare, da sinistra a destra e dall'alto verso il basso? O è una più o meno costretti a creare un'immagine mentale di spaghetti-come il cablaggio sulla pagina di codice che è decisamente non lineare? E se uno deve farlo, dobbiamo ancora leggere il codice, quindi come possiamo prendere un testo lineare e collegare gli spaghetti?
Eventuali suggerimenti sarebbero apprezzati.
const obj1 = { a:1, b:2, c:3, d:3 };
const obj2 = { a:1, b:1, e:2, f:2, g:3, h:5 };
// x or X is key or value or key/value pair
const getXs = (obj, getX) =>
Object.keys(obj).map(key => getX(obj)(key));
const getPctSameXs = (getX, filter = vals => vals) =>
(objA, objB) =>
filter(getXs(objB, getX))
.reduce(
(numSame, x) =>
getXs(objA, getX).indexOf(x) > -1 ? numSame + 1 : numSame,
0
) / Object.keys(objA).length * 100;
const pctSameKeys = getPctSameXs(obj => key => key);
const pctSameValsDups = getPctSameXs(obj => key => obj[key]);
const pctSameValsNoDups = getPctSameXs(obj => key => obj[key], vals => [...new Set(vals)]);
const pctSameProps = getPctSameXs(obj => key => JSON.stringify( {[key]: obj[key]} ));
console.log('obj1:', JSON.stringify(obj1));
console.log('obj2:', JSON.stringify(obj2));
console.log('% same keys: ', pctSameKeys (obj1, obj2));
console.log('% same values, incl duplicates:', pctSameValsDups (obj1, obj2));
console.log('% same values, no duplicates: ', pctSameValsNoDups(obj1, obj2));
console.log('% same properties (k/v pairs): ', pctSameProps (obj1, obj2));
// output:
// obj1: {"a":1,"b":2,"c":3,"d":3}
// obj2: {"a":1,"b":1,"e":2,"f":2,"g":3,"h":5}
// % same keys: 50
// % same values, incl duplicates: 125
// % same values, no duplicates: 75
// % same properties (k/v pairs): 25