¿Cómo invierte una cadena en su lugar (o in situ) en JavaScript cuando se pasa a una función con una declaración de retorno, sin usar las funciones integradas ( .reverse()
, .charAt()
etc.)?
javascript
string
reverse
Kobe
fuente
fuente
Respuestas:
Mientras trabaje con caracteres ASCII simples, y esté contento de usar las funciones integradas, esto funcionará:
Si necesita una solución que admita UTF-16 u otros caracteres de varios bytes, tenga en cuenta que esta función proporcionará cadenas Unicode no válidas o cadenas válidas que parecen divertidas. Es posible que desee considerar esta respuesta en su lugar .
[... s] es consciente de Unicode, una pequeña edición da: -
fuente
return [...s].reverse().join("");
puede funcionar.La siguiente técnica (o similar) se usa comúnmente para invertir una cadena en JavaScript:
De hecho, todas las respuestas publicadas hasta ahora son una variación de este patrón. Sin embargo, hay algunos problemas con esta solución. Por ejemplo:
Si te preguntas por qué sucede esto, lea sobre la codificación de caracteres interna de JavaScript . (TL; DR:
𝌆
es un símbolo astral, y JavaScript lo expone como dos unidades de código separadas).Pero hay más:
Una buena cadena para probar implementaciones inversas de cadena es la siguiente :
¿Por qué? Porque contiene un símbolo astral (
𝌆
) (que están representados por pares sustitutos en JavaScript ) y una marca de combinación (ñ
el últimomañana
realidad consta de dos símbolos: U + 006E LETRA PEQUEÑA LATINA N y U + 0303 TILDE COMBINADO).El orden en que aparecen los pares sustitutos no se puede invertir, de lo contrario, el símbolo astral ya no aparecerá en la cadena 'invertida'. Por eso viste esos
��
marcas en la salida del ejemplo anterior.Las marcas combinadas siempre se aplican al símbolo anterior, por lo que debe tratar tanto el símbolo principal (U + 006E LETRA PEQUEÑA LATINA N) como la marca combinada (U + 0303 TILDE COMBINADA) como un todo. Invertir su orden hará que la marca de combinación se empareje con otro símbolo en la cadena. Es por eso que la salida de ejemplo tenía
ã
lugar deñ
.Con suerte, esto explica por qué todas las respuestas publicadas hasta ahora son incorrectas .
Para responder a su pregunta inicial ( cómo invertir [correctamente] una cadena en JavaScript ), he escrito una pequeña biblioteca de JavaScript que es capaz de revertir cadenas con reconocimiento Unicode. No tiene ninguno de los problemas que acabo de mencionar. La biblioteca se llama Esrever. ; su código está en GitHub y funciona en prácticamente cualquier entorno de JavaScript. Viene con una utilidad / binario de shell, por lo que puede invertir fácilmente las cadenas de su terminal si lo desea.
En cuanto a la parte "en el lugar", vea las otras respuestas.
fuente
o
fuente
Análisis detallado y diez formas diferentes de invertir una cadena y sus detalles de rendimiento.
http://eddmann.com/posts/ten-ways-to-reverse-a-string-in-javascript/
Rendimiento de estas implementaciones:
Implementación (es) de mejor rendimiento por navegador
Aquí están esas implementaciones:
Implementación 1:
Implementación 2:
Implementación 3:
Implementación 4:
Implementación 5:
Implementación 6:
Implementación 7:
Implementación 8:
Implementación 9:
Implementación 10
fuente
Todo el "revertir una cadena en el lugar" es una pregunta de entrevista anticuada que los programadores de C, y las personas que fueron entrevistadas por ellos (¿por venganza, tal vez?), Preguntarán. Desafortunadamente, es la parte "In Place" que ya no funciona porque las cadenas en casi cualquier lenguaje administrado (JS, C #, etc.) usan cadenas inmutables, lo que anula la idea de mover una cadena sin asignar memoria nueva.
Si bien las soluciones anteriores sí invierten una cadena, no lo hacen sin asignar más memoria y, por lo tanto, no satisfacen las condiciones. Debe tener acceso directo a la cadena asignada y poder manipular su ubicación de memoria original para poder revertirla en su lugar.
Personalmente, realmente odio este tipo de preguntas de entrevistas, pero lamentablemente, estoy seguro de que las seguiremos viendo en los próximos años.
fuente
Primero, use
Array.from()
para convertir una cadena en una matriz, luegoArray.prototype.reverse()
para invertir la matriz y luegoArray.prototype.join()
para volverla una cadena.fuente
reverse
lógica preexistente .string.split('')
no funciona. Vea esta respuesta para más explicaciones.Array.from('foo 𝌆 bar mañana mañana').reverse().join('') == 'anãnam anañam rab 𝌆 oof'
Array.from('foo 𝌆 bar mañana mañana'.normalize('NFC')).reverse().join('')
se convertirá"anañam anañam rab 𝌆 oof"
En ECMAScript 6, puede invertir una cadena aún más rápido sin usar el
.split('')
método de división, con el operador de propagación de la siguiente manera:fuente
('')
string.split('')
es más claro para la mayoría de las personas que[...string]
..split('')
tiene el problema con los caracteres de los planos suplementarios (pares sustitutos en UTF-16), porque se divide por unidad de código UTF-16 en lugar de punto de código . El operador de propagación yArray.from()
(mi preferencia) no lo hacen.Parece que llego 3 años tarde a la fiesta ...
Lamentablemente no puede, como se ha señalado. Ver ¿Son las cadenas de JavaScript inmutables? ¿Necesito un "generador de cadenas" en JavaScript?
Lo mejor que puede hacer es crear una "vista" o "envoltorio", que tome una cadena y vuelva a implementar cualquier parte de la API de cadena que esté utilizando, pero simulando que la cadena se invierte. Por ejemplo:
Manifestación:
El pateador: lo siguiente se hace en el lugar por pura matemática, visitando a cada personaje solo una vez, y solo si es necesario:
Esto produce ahorros significativos si se aplica a una cadena muy grande, si solo está tomando una porción relativamente pequeña de la misma.
El hecho de que esto valga la pena (la reversión como una copia, como en la mayoría de los lenguajes de programación) depende en gran medida de su caso de uso y de la eficiencia con la que vuelva a implementar la API de cadena. Por ejemplo, si todo lo que desea es manipular el índice de la cadena, o tomar pequeños
slice
s osubstr
s, esto le ahorrará espacio y tiempo. Sin embargo, si planea imprimir grandes segmentos o subcadenas invertidas, los ahorros pueden ser pequeños, incluso peor que haber hecho una copia completa. Su cadena "invertida" tampoco tendrá el tipostring
, aunque es posible que pueda fingir esto con la creación de prototipos.La implementación de demostración anterior crea un nuevo objeto de tipo ReversedString. Tiene un prototipo y, por lo tanto, es bastante eficiente, con un trabajo casi mínimo y una sobrecarga de espacio mínima (se comparten las definiciones de los prototipos). Es una implementación perezosa que implica un corte diferido. Cada vez que realice una función como
.slice
o.reversed
, realizará matemáticas de índice. Finalmente cuando extrae datos (llamando implícitamente.toString()
o.charCodeAt(...)
o algo así), se aplicará a los de una manera "inteligente", tocando los mínimos datos posibles.Nota: la API de cadena anterior es un ejemplo, y puede no implementarse perfectamente. También puede usar solo 1-2 funciones que necesita.
fuente
Hay muchas formas de invertir una cadena en JavaScript. Estoy anotando tres formas que prefiero.
Enfoque 1: Uso de la función inversa:
Enfoque 2: Recorriendo los personajes:
Enfoque 3: Uso de la función de reducción:
Espero que esto ayude :)
fuente
Durante una entrevista, me pidieron que invirtiera una cadena sin usar ninguna variable o método nativo. Esta es mi implementación favorita:
fuente
slice
? : - /Array.prototype.reverse()
.Hay varias formas de hacerlo, puede verificar lo siguiente,
1. Tradicional para bucle (incremental):
2. Tradicional para bucle (decremento):
3. Usando for-of loop
4. Usando el método de matriz forEach / high order:
5. Norma ES6:
6. La última forma:
7. También puede obtener el resultado usando lo siguiente,
fuente
En ES6, tienes una opción más
fuente
Esta es la forma más fácil que creo.
fuente
Array.prototype.reverse()
eso sería la forma más fácil, de ahí la respuesta más popular. Por supuesto, requeriría un buen conocimiento previo de JavaScript.O
// Salida: 'gnirts elpmas'
fuente
[...str]
.Sé que esta es una vieja pregunta que ha sido bien respondida, pero para mi propia diversión escribí la siguiente función inversa y pensé que la compartiría en caso de que fuera útil para cualquier otra persona. Maneja ambos pares sustitutos y marcas combinadas:
Todos los accesorios para Mathias, Punycode y varias otras referencias para enseñarme sobre las complejidades de la codificación de caracteres en JavaScript.
fuente
No puede porque las cadenas JS son inmutables. Solución corta no en el lugar
Mostrar fragmento de código
fuente
Si no desea utilizar ninguna función integrada. Prueba esto
fuente
La respuesta real es: no puede revertirlo en su lugar, pero puede crear una nueva cadena que sea la inversa.
Solo como un ejercicio para jugar con la recursividad: a veces, cuando vas a una entrevista, el entrevistador puede preguntarte cómo hacer esto usando la recursividad, y creo que la "respuesta preferida" podría ser "Prefiero no hacerlo en la recursión ya que puede causar fácilmente un desbordamiento de la pila "(porque es
O(n)
más queO(log n)
. Si es asíO(log n)
, es bastante difícil obtener un desbordamiento de la pila: un nivel de pila de 32 podría manejar 4 mil millones de elementos, ya que 2 ** 32 es 4294967296. Pero si es asíO(n)
, entonces puede obtener fácilmente un desbordamiento de pila.A veces, el entrevistador aún te preguntará, "solo como ejercicio, ¿por qué no lo escribes usando la recursividad?" Y aquí está:
prueba de funcionamiento:
salida:
Para intentar obtener un desbordamiento de la pila, cambié
1000
a10000
Google Chrome e informó:fuente
Las cadenas en sí son inmutables, pero puede crear fácilmente una copia invertida con el siguiente código:
fuente
fuente
Una pequeña función que maneja tanto la combinación de diacríticos como los caracteres de 2 bytes:
Actualizar
Una lista más completa de combinación de diacríticos es:
fuente
isCombiningDiacritic
función para incluir todos los rangos 316; no dude en proporcionar esa edición, ya que parece tener los datos a mano.fuente
sin convertir una cadena en una matriz;
usando Array.reverse sin convertir caracteres en puntos de código;
fuente
var c = array[i-1]; array[i-1] = array[i]; array[i] = c;
no requiere concatenar el par de códigos. Además, el ciclo for debería comenzar en 1.'\ud83c\ud83c\udfa5'.reverse()
: generará lo mismo que la entrada. Agregar++i;
dentro de laif
declaración debería solucionar esto.'a\u0303bc'.reverse() === 'cba\u0303'
debería ser verdadero.Creo que String.prototype.reverse es una buena manera de resolver este problema; el código de la siguiente manera;
fuente
Usando funciones de matriz,
fuente
fuente
Mi propio intento original ...
http://jsbin.com/bujiwo/19/edit?js,console,output
fuente
¡Manténgalo SECO y simple tonto!
fuente
OK, bastante simple, puedes crear una función con un bucle simple para hacer que la cadena se invierta sin usar
reverse()
,charAt()
etc. , así:Por ejemplo, tienes esta cadena:
Crea una función como esta, lo llamo
reverseString
...Y puedes llamarlo así:
Y el resultado será:
fuente
Las mejores formas de revertir una cadena en JavaScript
1) Array.reverse:
Probablemente estés pensando, espera, pensé que estábamos invirtiendo una cadena, ¿por qué estás usando el método Array.reverse? Usando el método String.split estamos convirtiendo nuestra cadena en una matriz de caracteres. Luego estamos invirtiendo el orden de cada valor en la matriz y finalmente convertimos la matriz nuevamente en una cadena usando el método Array.join.
2) Disminución del ciclo while:
Aunque bastante detallada, esta solución tiene sus ventajas sobre la solución uno. No está creando una matriz y solo está concatenando una cadena basada en caracteres de la cadena de origen.
Desde una perspectiva de rendimiento, este probablemente arrojaría los mejores resultados (aunque no probado). Sin embargo, para cadenas extremadamente largas, las ganancias de rendimiento pueden caerse por la ventana.
3) recursividad
Me encanta lo simple y clara que es esta solución. Puede ver claramente que los métodos String.charAt y String.substr se están utilizando para pasar a través de un valor diferente al llamarse cada vez hasta que la cadena esté vacía, de lo cual el ternario simplemente devolvería una cadena vacía en lugar de usar la recursión para llamarse . Esto probablemente produciría el segundo mejor rendimiento después de la segunda solución.
fuente