Ci sono molti nomi di variabili più validi di quelli generati dalla serie nella tua domanda, ma ci andrò perché è semplice e potrebbe essere abbastanza buono.
Idealmente dovremmo tenere traccia di quante variabili sono state generate e semplicemente mappare quel numero al nome della variabile successiva. Affrontare la variabile nameSeed
incrementale dovrebbe essere semplice, e c'è una funzione molto utile per il prossimo passo in JavaScript, che corrisponde esattamente alla nostra funzionalità desiderata quasi : Number#toString(radix)
. radix
è 10 di default (dando la rappresentazione decimale del numero) ma può essere fino a 36, che include non solo le cifre 0-9 ma anche le lettere a-z.
Ad esempio, (30).toString(36)
dà u
. (400).toString(36)
dà b4
. Sfortunatamente, (1).toString(36)
fornisce 1
, che non è un identificatore valido e ci sono infinitamente più casi in cui si verifica lo stesso tipo di errore ...
Se vuoi solo "tipo di minimo", puoi anteporre _
e avere un identificatore valido.
Se vuoi veramente minimo (entro i limiti di 0-9, a-z), dobbiamo modificare l'algoritmo per evitare quei nomi non validi. Dobbiamo anche evitare cose come undefined
, var
, ecc. Potrebbe esserci una buona strategia per fare questo "in modo preventivo", ma semplicemente convaliderò il risultato e correggendolo (così come la nameSeed
) se ha bisogno di essere riparato.
La funzione seguente accetta un seme da utilizzare per il nome e restituisce il nome generato e il successivo potenziale seme. Se il seme dato produce un risultato non valido, utilizza il primo seme valido più grande del seme dato (se tutti i semi fossero validi, non dovremmo restituire il "prossimo", ma ora è necessario poiché potremmo aver saltato un po ').
function generateName( seed ) {
var name = seed.toString( 36 );
if ( isNaN( name.substring( 0, 1 ) ) ) {
// The name starts with a letter, now see if it collides with any builtins
if ( builtins.indexOf( name ) < 0 ) {
// Got a good name
return { nextSeed: seed + 1, name: name };
} else {
// There's a collision, try the next seed
return generateName( seed + 1 );
}
} else {
// The name starts with a digit, just replace it with 'a' and try again
// We could use the same strategy as above (just increment seed), but that might take a long time... better to jump to something with a good chance of working.
name = "a" + name.substring( 1 );
var newSeed = parseInt( name, 36 );
return generateName( newSeed );
}
}
Costruire l'array builtins
è lasciato come esercizio per il lettore ...