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 substrinvece di slice.
Altre soluzioni che ho provato che coinvolgono splito RegExps ha avuto un grande calo di prestazioni e sono stati circa 2 ordini di grandezza più lento. Utilizzando joinsui 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 splitcrea) 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 RegExpo splitsoluzione 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.