¿La solución más rápida?
Ejecuté algunos puntos de referencia , y esta solución ganó 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);
};
Comparación de rendimiento con otras soluciones.
El único competidor cercano era la misma línea de código, excepto el uso en substrlugar de slice.
Otras soluciones que probé involucrando splito RegExps tuvieron un gran éxito de rendimiento y fueron aproximadamente 2 órdenes de magnitud más lentas. Usar joinlos resultados de split, por supuesto, agrega una penalización de rendimiento adicional.
¿Por qué son más lentos? Cada vez que se debe crear un nuevo objeto o matriz, JS tiene que solicitar una porción de memoria del sistema operativo. Este proceso es muy lento.
Aquí hay algunas pautas generales, en caso de que esté persiguiendo puntos de referencia:
- Las nuevas asignaciones de memoria dinámica para objetos
{}o matrices [](como la que splitcrea) costarán mucho en rendimiento.
RegExp Las búsquedas son más complicadas y, por lo tanto, más lentas que las búsquedas de cadenas.
- Si ya tiene una matriz, la desestructuración de las matrices es casi tan rápida como indexarlas explícitamente, y se ve increíble.
Eliminar más allá de la primera instancia
Aquí hay una solución que se dividirá e incluirá la enésima instancia. No es tan rápido, pero en la pregunta del OP, gobble(element, '_', 1)todavía es> 2 veces más rápido que una RegExpo splitsolución y puede hacer más:
/*
`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 definición anterior, gobble('path/to/file.txt', '/')daría el nombre del archivo y gobble('prefix_category_item', '_', 1)eliminaría el prefijo como la primera solución en esta respuesta.
- Las pruebas se ejecutaron en Chrome 70.0.3538.110 en macOSX 10.14.