Soluzione più veloce?
Ho eseguito alcuni benchmark e questa soluzione ha vinto enormemente: 1
str.slice(str.indexOf(delim) + delim.length)
// as function
function gobbleStart(str, delim) {
return str.slice(str.indexOf(delim) + delim.length);
}
// as polyfill
String.prototype.gobbleStart = function(delim) {
return this.slice(this.indexOf(delim) + delim.length);
};
Confronto delle prestazioni con altre soluzioni
L'unico contendente stretto era la stessa riga di codice, tranne usare substr
invece di slice
.
Altre soluzioni che ho provato che coinvolgono split
o RegExp
s ha avuto un grande calo di prestazioni e sono stati circa 2 ordini di grandezza più lento. Utilizzando join
sui risultati di split
, ovviamente, si aggiunge una penalità aggiuntiva per le prestazioni.
Perché sono più lenti? Ogni volta che deve essere creato un nuovo oggetto o array, JS deve richiedere un pezzo di memoria dal sistema operativo. Questo processo è molto lento.
Ecco alcune linee guida generali, nel caso tu stia inseguendo benchmark:
- Le nuove allocazioni di memoria dinamica per oggetti
{}
o matrici []
(come quella che split
crea) costeranno molto in termini di prestazioni.
RegExp
le ricerche sono più complicate e quindi più lente delle ricerche di stringhe.
- Se disponi già di un array, gli array destrutturanti sono veloci quanto indicizzarli esplicitamente e sembrano fantastici.
Rimozione oltre la prima istanza
Ecco una soluzione che si suddividerà e includerà l'ennesima istanza. Non è altrettanto veloce, ma sulla domanda del PO, gobble(element, '_', 1)
è ancora> 2x più veloce di una RegExp
o split
soluzione e può fare di più:
/*
`gobble`, given a positive, non-zero `limit`, deletes
characters from the beginning of `haystack` until `needle` has
been encountered and deleted `limit` times or no more instances
of `needle` exist; then it returns what remains. If `limit` is
zero or negative, delete from the beginning only until `-(limit)`
occurrences or less of `needle` remain.
*/
function gobble(haystack, needle, limit = 0) {
let remain = limit;
if (limit <= 0) { // set remain to count of delim - num to leave
let i = 0;
while (i < haystack.length) {
const found = haystack.indexOf(needle, i);
if (found === -1) {
break;
}
remain++;
i = found + needle.length;
}
}
let i = 0;
while (remain > 0) {
const found = haystack.indexOf(needle, i);
if (found === -1) {
break;
}
remain--;
i = found + needle.length;
}
return haystack.slice(i);
}
Con la definizione sopra, gobble('path/to/file.txt', '/')
darebbe il nome del file e gobble('prefix_category_item', '_', 1)
rimuoverà il prefisso come la prima soluzione in questa risposta.
- I test sono stati eseguiti in Chrome 70.0.3538.110 su macOSX 10.14.