vasos tutorial lenguaje google español container dart

tutorial - ¿Cómo puedo revertir una cadena en Dart?



dart vasos (5)

Tengo una cadena, y me gustaría revertirla. Por ejemplo, estoy escribiendo un filtro AngularDart que invierte una cadena. Es solo para fines de demostración, pero me hizo preguntarme cómo invertir una cadena.

Ejemplo:

Hello, world

debe convertirse en:

dlrow ,olleH

También debería considerar cadenas con caracteres Unicode. Por ejemplo: ''Ame/u{301}lie''

¿Qué es una manera fácil de revertir una cadena, incluso si la tiene?


Aquí hay una forma de revertir una cadena ASCII en Dart:

input.split('''').reversed.join('''');

  1. dividir la cadena en cada carácter, creando una lista
  2. generar un iterador que invierte una lista
  3. unirse a la lista (creando una nueva cadena)

Nota: esta no es necesariamente la forma más rápida de revertir una cadena. Vea otras respuestas para alternativas.

Nota: esto no maneja adecuadamente todas las cadenas Unicode.


He hecho un pequeño punto de referencia para algunas alternativas diferentes:

String reverse0(String s) { return s.split('''').reversed.join(''''); } String reverse1(String s) { var sb = new StringBuffer(); for(var i = s.length - 1; i >= 0; --i) { sb.write(s[i]); } return sb.toString(); } String reverse2(String s) { return new String.fromCharCodes(s.codeUnits.reversed); } String reverse3(String s) { var sb = new StringBuffer(); for(var i = s.length - 1; i >= 0; --i) { sb.writeCharCode(s.codeUnitAt(i)); } return sb.toString(); } String reverse4(String s) { var sb = new StringBuffer(); var i = s.length - 1; while (i >= 3) { sb.writeCharCode(s.codeUnitAt(i-0)); sb.writeCharCode(s.codeUnitAt(i-1)); sb.writeCharCode(s.codeUnitAt(i-2)); sb.writeCharCode(s.codeUnitAt(i-3)); i -= 4; } while (i >= 0) { sb.writeCharCode(s.codeUnitAt(i)); i -= 1; } return sb.toString(); } String reverse5(String s) { var length = s.length; var charCodes = new List(length); for(var index = 0; index < length; index++) { charCodes[index] = s.codeUnitAt(length - index - 1); } return new String.fromCharCodes(charCodes); } main() { var s = "Lorem Ipsum is simply dummy text of the printing and typesetting industry."; time(''reverse0'', () => reverse0(s)); time(''reverse1'', () => reverse1(s)); time(''reverse2'', () => reverse2(s)); time(''reverse3'', () => reverse3(s)); time(''reverse4'', () => reverse4(s)); time(''reverse5'', () => reverse5(s)); }

Aquí está el resultado:

reverse0: => 331,394 ops/sec (3 us) stdev(0.01363) reverse1: => 346,822 ops/sec (3 us) stdev(0.00885) reverse2: => 490,821 ops/sec (2 us) stdev(0.0338) reverse3: => 873,636 ops/sec (1 us) stdev(0.03972) reverse4: => 893,953 ops/sec (1 us) stdev(0.04089) reverse5: => 2,624,282 ops/sec (0 us) stdev(0.11828)


La biblioteca More Dart contiene una envoltura liviana alrededor de cadenas que los hace comportarse como una lista de caracteres inmutables:

import ''package:more/iterable.dart''; void main() { print(string(''Hello World'').reversed.join()); }


La pregunta no está bien definida. Invertir cadenas arbitrarias no tiene sentido y dará lugar a una salida rota. El primer obstáculo (superable) es Utf-16. Las cadenas de dardos se codifican como Utf-16 y la inversión de solo las unidades de código conduce a cadenas no válidas:

var input = "Music /u{1d11e} for the win"; // Music 𝄞 for the win print(input.split('''').reversed.join()); // niw eht rof

La función de split advierte explícitamente contra este problema (con un ejemplo):

La división con un patrón de cadena vacío ('''') se divide en los límites de las unidades de código UTF-16 y no en los límites de la runa [.]

Hay una solución fácil para esto: en lugar de revertir las unidades de código individuales, se pueden revertir las runas:

var input = "Music /u{1d11e} for the win"; // Music 𝄞 for the win print(new String.fromCharCodes(input.runes.toList().reversed)); // niw eht rof 𝄞 cisuM

Pero eso no es todo. Las runas también pueden tener un orden específico. Este segundo obstáculo es mucho más difícil de resolver. Un ejemplo simple:

var input = ''Ame/u{301}lie''; // Amélie print(new String.fromCharCodes(input.runes.toList().reversed)); // eiĺemA

Tenga en cuenta que el acento está en el carácter incorrecto.

Probablemente hay otros idiomas que son aún más sensibles al orden de las runas individuales.

Si la entrada tiene restricciones severas (por ejemplo, ser Ascii o Iso Latin 1), técnicamente es posible revertir las cadenas. Sin embargo, todavía no he visto un solo caso de uso en el que esta operación tuviera sentido.

Usar esta pregunta como ejemplo para mostrar que las cadenas tienen operaciones similares a una lista tampoco es una buena idea. Excepto en algunos casos de uso, las cadenas deben tratarse con respecto a un idioma específico y con métodos altamente complejos que tienen conocimientos específicos del idioma.

En particular, los hablantes nativos de inglés deben prestar atención: las cadenas rara vez se pueden manejar como si fueran listas de caracteres individuales. En casi todos los demás idiomas, esto conducirá a programas de buggy. (Y no me toLowerCase comenzar con toLowerCase y toUpperCase ...).


Prueba esta funcion

String reverse(String s) { var chars = s.splitChars(); var len = s.length - 1; var i = 0; while (i < len) { var tmp = chars[i]; chars[i] = chars[len]; chars[len] = tmp; i++; len--; } return Strings.concatAll(chars); } void main() { var s = "Hello , world"; print(s); print(reverse(s)); }

(o)

String reverse(String s) { StringBuffer sb=new StringBuffer(); for(int i=s.length-1;i>=0;i--) { sb.add(s[i]); } return sb.toString(); } main() { print(reverse(''Hello , world'')); }